加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-17 07:27:04 所属栏目:安全 来源:网络整理
导读:我正在尝试清理某些文本区域的内容,我不能使用ng-bind-html,因为它打破了双向绑定(ng-model不能同时工作) 奇怪的是,当我将ng-bind-html应用于模型时,它会产生不同的结果,当我在指令中使用$sanitize或$sce时. 这是我编写的一个示例 http://plnkr.co/edit/iRvK
我正在尝试清理某些文本区域的内容,我不能使用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);
};

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读