0

I am a noob with angularjs and I have a problem. I am using prism.js or highlights.js in my web (same result). It works correctly into index.html but It doesn't work in other templates that I load with ngRoute. I believe that the problem is angularjs only it renders one more time the html and it doesn't work when I load my content-principal.html.

INDEX.HTML

//<pre><code class="language-javascript">
    colour syntax is ok
//</code></pre>

APP.JS

ionicEsApp.config(function($routeProvider) {
    $routeProvider.
    when('/', {
        templateUrl: 'templates/content-principal.html',
        //controller: 'IonicEsController'
 }).

content-principal.html

//<pre><code class="language-javascript">
    colour syntax is NO work
//</code></pre>

¿any solution? Thanks and sorry by my english :P.

CarmaZone
  • 21
  • 4
  • You need to wrap up the third party library in a service or a directive. Since Angulary is dynamically changing the DOM to insert templates etc. the highlight code needs to be executed after the DOM is manipulated. Typically the way to do this is to use a directive or in some cases a service/factory for wrapping up the third party library functionality. Search to see if existing directives for these libraries exist or else start reading the docs on how to write your own directives that can be applied to DOM elements in the view. – shaunhusain Feb 02 '15 at 17:31
  • Ok, I understand it. Thanks so much. I'll search information about that. – CarmaZone Feb 02 '15 at 17:40
  • worked on index page, but not working on partial views. what is exactly working, what is not working. can you please eloborate? – Pankaj Parkar Feb 02 '15 at 17:45
  • prism.js and highligths are a libraries to syntax highlighter. How said shaunhusain I will need a directive. I know the problem now and I found different articles to try it: http://webtoutsaint.com/prismjs_eng http://maxisam.github.io/blog/2013/01/15/using-directive-to-work-with-highlight-dot-js/ – CarmaZone Feb 02 '15 at 18:06

3 Answers3

2

SOLVED.

We need:

index.html

prims.js and prism.css from http://prismjs.com/#basic-usage

app.js

To create a new directive (VERY IMPORTANT before from .conf)

var ionicEsApp = angular.module('ionicEsApp', [
    'ngRoute',
    'ngResource',
    'ionicEsController'
]);

ionicEsApp.directive('ngPrism', [function() {
    return {
        restrict: 'A',
        link: function($scope, element, attrs) {
            element.ready(function() {
                Prism.highlightElement(element[0]);
            });
        }
    }
}]);

ionicEsApp.config(function($routeProvider) {
    $routeProvider.
    when('/', {
        templateUrl: 'templates/content-principal.html',
        //controller: 'IonicEsController'
    }).
    otherwise({
        redirectTo: '/'
    });

});

content-principal.html

We have to use the new directive into code tag.

<pre><code ng-prism class="language-javascript">
    alert("Prims is ok");
</code></pre>

NOTE: There is a problem with html, we need replace the < symbol by &lt. Example:

<pre><code class="language-markup">
&lth1> Hello! &lt/h1>
</code></pre>
CarmaZone
  • 21
  • 4
0

Can't comment on an answer yet, but I found this technique useful.

If you load your templates 'manually' and insert the text into the dom, Angular will automagically convert the content to HTML entities, meaning your raw template are still readable, but display correctly.

In my application I use $sce and $templateRequest to get the template, then set an angular template variable to the value of the fetched template.

A couple of notes:

  • I have multiple code samples per directive instance, identified by a codeType variable
  • My templates filenames are in the form of _{codeType}.sample e.g. _css.sample
  • The template location is passed in as an attribute of the directive in the dom
  • The dom element containers are identified by class .sample-{codeType} e.g .sample-css
  • The angular placeholder is identified by {{sample{codeType}} e.g. {{samplecss}}
  • To prevent race conditions, I use $timeout to wait a beat and allow the current $apply() to complete before calling Prism on the code.

This method also allows for multiple types of code with similar outputs - for example, in my styleguide I show both the output HTML (codeType = 'html') and the un-rendered Angular templates (codeType = 'ng') - both require the Prism .language-markup class.

This can be simplified a lot if you only have one code sample per directive.

function StyleGuideComponentController($scope, $element, $templateRequest, $sce, $timeout)
{
    var codeSampleTypes =
    [
        'html',
        'ng',
        'ngjs',
        'css',
        'less'
    ];

    insertAllCodeSamples();

    function insertAllCodeSamples()
    {
        var key;

        for (key in codeSampleTypes)
        {
            insertCodeSample(codeSampleTypes[key]);
        }
    }

    function insertCodeSample(codeType)
    {
        var sampleUrl = $scope.templateLocation + '/_' + codeType + '.sample',
            sampleCode = $sce.getTrustedResourceUrl(sampleUrl);

        $templateRequest(sampleCode).then(function(template)
        {
            var codeElement    = $element.find('.sample-' + codeType)[0],
                prismLanguage      = codeType,
                prismLanguageTypes =
                {
                    'html' : 'markup',
                    'ng'   : 'markup',
                    'js'   : 'javascript',
                    'ngjs' : 'javascript'
                },
                key;

            for (key in prismLanguageTypes)
            {
                if (prismLanguage === key)
                {
                    prismLanguage = prismLanguageTypes[key];
                }
            }

            codeElement.className += ' language-' + prismLanguage;

            $scope['sample' + codeType] = template;

            $timeout(function()
            {
                Prism.highlightElement(codeElement);
            });
        }, function()
        {
            $scope['sample' + codeType] = 'An error occurred' +
            ' while fetching the code sample';
        });
    }

    return {
        restrict   : 'E',
        scope      :
        {
            templateLocation: '='
        },
        controller : StyleGuideComponentController
    };
}
0

There is a really easy way to do this if you are using ng-view to load the template:

if you have something like this:

<div ng-controller="MainCtrl">
     <div id="content" ng-view>
     </div>
</div>

You can add this to your MainCtrl controller:

$scope.$on('$viewContentLoaded', function(){
    Prism.highlightAll();
});

Now, if you use the default way to highlight the code:

<pre><code class="language-javascript">
     Prism will highlight it
</code></pre>

Prism will highlight it!

Yash Patel
  • 21
  • 1
  • 6
  • I know this is a late answer, but I felt this was the easiest way as you don't have to put ng-prism all the time to the
     tags and you can just use the normal way of prism.js syntax highlighting
    – Yash Patel Dec 27 '16 at 03:45