angularjs – 为什么ng-bind-html和$sanitize产生不同的结果?

我正在尝试清理某些文本区域的内容,我不能使用ng-bind-html,因为它打破了双向绑定(ng-model不能同时工作)

奇怪的是,当我将ng-bind-html应用于模型时,它会产生不同的结果,当我在指令中使用$sanitize或$sce时.

这是我编写的一个示例

http://plnkr.co/edit/iRvK4med8T9Xqs22BkOe?p=preview

一个文本区域使用ng-bind-html,第二个文本区域使用$sanitize,第三个应该是ng-bind-html指令的代码,因为我从AngularJS源代码删除了.

&安培; QUOT;只有更正改为“当使用ng-bind-html时,在另外两个例子中它改为"

如何在我的指令中复制ng-bind-html的结果 – 同时保持双向绑定?

angular.module('sanitizeExample',['ngSanitize'])
  .controller('ExampleController',['$scope','$sce',function($scope,$sce) {

      $scope.value = 'This in "quotes" for testing';
      $scope.model = 'This in "quotes" for testing';

    }
  ]).directive('sanitize',['$sanitize','$parse',function($sanitize,$parse,$sce) {
      return {
        restrict: 'A',replace: true,scope: true,link: function(scope,element,attrs) {

          var process = function(input) {
            return $sanitize(input);
            //return $sce.getTrustedHtml(input);
          };

          var processed = process(scope.model);
          console.log(processed); // Output here = This in "quotes" for testing
          $parse(attrs.ngModel).assign(scope,processed);
          //element.html(processed);
        }
      };
    }
  ])
  .directive('sanitizeBindHtml',['$parse',function($parse,attrs) {

          var parsed = $parse(attrs.ngModel);

          function getStringValue() {
            var value = parsed(scope);
            getStringValue.$$unwatch = parsed.$$unwatch;
            return (value || '').toString();
          }

          scope.$watch(getStringValue,function ngBindHtmlWatchAction(value) {
            var processed = $sce.getTrustedHtml(parsed(scope)) || '';

            $parse(attrs.ngModel).assign(scope,processed)
          });
        }
      };
    }
  ]);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-sanitize.js"></script>

<!doctype html>
<html lang="en">


<body ng-app="sanitizeExample">

  <div ng-controller="ExampleController">
    <textarea ng-bind-html="value"></textarea>
    <br/>{{value}}
    <br/>
    <br/>
    <textarea sanitize ng-model="model"></textarea>
    <br/>
    <br/>
    <textarea sanitize-bind-html ng-model="model"></textarea>

  </div>
</body>
结果就像我们所期望的那样,卫生服务正在返回相同的结果.在 ngBindHtmlDirective内放置一个断点,我们可以介入,看看发生了什么.我们深入研究并检查 $SanitizeProvider内的值.将返回到ngBindHtmlDirective的buf值为:

This in &#34;quotes&#34; for testing

与我们调用$sanitize完全相同,那么真正的区别是什么?真正的区别在于文本框的innerHTML和值之间.查看此example plunker.您可以看到调用两种不同方法间的区别,使用不同的方法来转义双引号.我没有去挖掘w3规范或浏览器代码,但我认为innerHTML赋值是在创建documentFragment,抓取它的textContent,然后将其分配给文本框的值的引擎下做额外的工作.显然,值只是抓住字符串并按原样插入.

那么你的指令有什么问题呢?我看到element.html(已处理)在评论中,但取消注释它没有影响.事实上,它确实可以工作一瞬间!使用调试器逐步调试,文本框的值已正确设置,但随后会触发$digest循环并立即更改它!事实是ngModelDirective正在阻碍,特别是它是$render function of the baseInputType.我们可以在代码中看到它正在使用element.val方法.

我们如何在指令中解决这个问题?需要ngModelController并覆盖其$render函数以改为使用element.html方法(example plunker).

// Add require to get the controller
require: 'ngModel',// Controller is passed in as the 4th argument
link: function(scope,attrs,ngModelCtrl) {

// modify the $render function to process it as HTML
ngModelCtrl.$render = function() {
    element.html(ngModelCtrl.$isEmpty(ngModelCtrl.$viewValue) ? '' : ngModelCtrl.$viewValue);
};

相关文章

ANGULAR.JS:NG-SELECTANDNG-OPTIONSPS:其实看英文文档比看中...
AngularJS中使用Chart.js制折线图与饼图实例  Chart.js 是...
IE浏览器兼容性后续前言 继续尝试解决IE浏览器兼容性问题,...
Angular实现下拉菜单多选写这篇文章时,引用文章地址如下:h...
在AngularJS应用中集成科大讯飞语音输入功能前言 根据项目...
Angular数据更新不及时问题探讨前言 在修复控制角标正确变...