Calling prettyPrint() dynamically in AngularJS ruins binding

喜夏-厌秋 提交于 2019-12-08 04:32:19

问题


I'm trying to prettify some text that is generated dynamically.

<div ng-app="Knob" ng-controller="myCtrl">
    <pre class="prettyprint">{{text}}</pre>
</div>

var App = angular.module('Knob', []);
App.controller('myCtrl', function($scope) {
   $scope.text = "hello world";
})

App.directive('prettyprint', function() {
    return {
        restrict: 'C',
        link: function postLink(scope, element, attrs) {
              prettyPrint();
        }
    };
});

The output:

hello worldtext}}

Any ideas why?

http://jsfiddle.net/yAv4f/62/


回答1:


It can be achieved by a small directive. Find the answer here AngularJs how to call prettyprint?

I would like to make a small addition to the directive by @carlosmantilla

You can achieve the same thing without creating the scope variable. I have added this correction on github

This should work properly I assume.

http://jsfiddle.net/yAv4f/143/

var App = angular.module('Knob', []);
App.controller('myCtrl', function($scope) {
    $scope.text = "function f1(){int a;}";
})

function replaceText(str)
{
    var str1 = String(str);
    return str1.replace(/\n/g,"<br/>");
}

app.directive('prettyprint', function() {
    return {
        restrict: 'C',
        link: function postLink(scope, element, attrs) {
              element.html(prettyPrintOne(replaceText(element.html()),'',true));
        }
    };
});



回答2:


this is a late reply and im sure that you have solved the problem. However there may be some other people stumbling upon this thread with the same problem. I solved this using and adapted version of google-code prettify, which can be found here: https://github.com/angular/code.angularjs.org/tree/master/1.3.0-beta.3/docs/components/google-code-prettify-1.0.1 Simply follow the instructions on that page.

Now, prettifyPrint() can be called globally.

(function(){
    $('pre').addClass('prettyprint');
    prettyPrint();
})();

I placed this at the bottom of my dynamic template




回答3:


Hard to say, what does prettyPrint() should return ?

It seems quite strange that you don't give any arguments to prettyPrint...

By the way, I think an angular filter would be a better fit for your need instead of a directive.

[EDIT]

This one is working "dynamically" using filter :

html :

<div ng-app="Knob" ng-controller="myCtrl">
    <!--<input ng-model="text" type="text"/>-->
    <pre ng-bind-html-unsafe="text|pretty"></pre>
</div>

js :

var App = angular.module('Knob', []);
App.controller('myCtrl', function($scope) {
    setTimeout(function() {
        $scope.text = "class Voila {};";
        $scope.$apply();
    }, 0);
});

App.filter('pretty', function(){
    return function(text) {
        return prettyPrintOne(text);
    }
})

You can see it at

http://jsfiddle.net/cSXpV/1/

You can uncomment the input to change directly the text that will be prettyfied

Note that this version is for Angular 1.1.1 (the version you choosed in your initial jsfiddle), for Angular 1.2.*, you have to use ng-bind-html and the ngSanitize module

Last point : now that it is dynamically prettyfied, the setTimeOut and $scope.$apply can be removed (info for readers)

[/EDIT]




回答4:


My directive. It s waiting for $viewContentLoaded to be sure the template var({{}}) in it have already been computed by angular. should be used in a <pre>

.directive('prettyprint', function() {
  return {
    restrict: 'C',
    link: function postLink(scope, element) {
      scope.$on('$viewContentLoaded', function(){
        element.html(prettyPrintOne(element.html(),'',true));
      });
    }
  };
});



回答5:


Please try using ng-bind-html.

<div ng-app="Knob" ng-controller="myCtrl">
    <pre class="prettyprint" ng-bind-html="text"></pre>
</div>


app.directive('prettyprint', function() {
    return {
        restrict: 'C',
        link: function postLink(scope, element, attrs) {
          element.html(prettyPrintOne(element.html(),'',true));
        }
    };
});



回答6:


I don't know why, but I find out if you delay 300ms to execute the prettyprint function, it works well. see below:

var App = angular.module('Knob', []);
App.controller('myCtrl', function($scope) {
   $scope.text = "hello world";
})

App.directive('prettyprint', function() {
    return {
        restrict: 'C',
        link: function postLink(scope, element, attrs) {
              setTimeout(prettyPrint,300);
        }
    };
});


来源:https://stackoverflow.com/questions/21081950/calling-prettyprint-dynamically-in-angularjs-ruins-binding

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!