【问题标题】:$sce.trustAsHtml and ng-show$sce.trustAsHtml 和 ng-show
【发布时间】:2015-07-04 10:29:51
【问题描述】:

http://codepen.io/pondnetic/pen/qdxGVV

我的 ionic 应用程序中显示了几行 html 的 javascript 字符串

<div ng-bind-html="strVar | to_trusted"></div>

to_trusted 是一个使用 $sce 的简单过滤器

    .filter('to_trusted', ['$sce', function($sce){
  return function(text) {
    return $sce.trustAsHtml(text);
  };
}])

如codepen所示,以这种方式显示html时,ng-show和ng-hide不起作用。我怎样才能让它按预期运行?

【问题讨论】:

  • 没有足够详细的答案,但角度基本上不是将您的 HTML 作为模板,而是作为原始 HTML。您应该了解如何动态加载模板。
  • 正如 Alpha 所说,您正在添加未编译的 HTML。这是你在指令中做的事情,而不是控制器。
  • 我想说在这种情况下识别错误并指出正确的方向绝对足以保证答案,@Alpha。
  • “当然,@Jan。” (对不起,不得不抓住机会。)说真的,我只是写了一个详细的答案,你可以看到为什么我认为它不适合评论。感谢您的鼓励——这是我开始写答案的第一个原因。 =)
  • 哇,太过分了,干得好。我认为由于解决方案远远超出了问题的范围,指向正确的方向就足以保证答案。

标签: javascript html angularjs ionic


【解决方案1】:

您遇到的当前问题是 Angular 将您的文本作为 HTML 正确,正如您所希望的那样,但是这样做之后,它不会像 Angular 模板那样绑定到新的属性和类。

这种行为并不是 Angular 设计的缺陷,而是防止特定指令无法使网站完全无响应。想想如果它需要为新的指令和绑定重新评估生成的每条新 HTML,它很可能会进入一个永无止境的执行和检查循环。

不要使用动态模板

解决问题的第一种方法是改变方法:不要使用动态模板。您这样做的原因很可能是允许用户输入来生成模板(这会成为一个安全问题,可能是 XSS 的入口),或者第三方系统正在为您生成 HTML,这这也是一个坏主意,因为关注点与系统分离(如果您的系统应该生成 HTML,则不应混淆其他来源,更不用说信任它们了)。

使用指令

如果您插入 HTML 的原因是为了重用 HTML,那么您可能正在寻找 directives,这是一个 Angular 组件,它可以让您做到这一点:重用和隔离与生成的 HTML 紧密耦合的行为。

这是来自directive documentation 的一个简单示例:

动态模板

如果您真的想进入动态模板,有一种方法可以做到。您将以与上面示例完全相同的方式创建指令,但不是将模板硬编码到指令(或模板文件)中,您可以动态地将模板的内容输入link 函数并编译它您自己使用提供的范围,如下所示:

angular.module('variableDirective', [])
  .controller('Controller', ['$scope', function($scope) {
    $scope.customer1 = {
      name: 'Naomi',
      address: '1600 Amphitheatre'
    };
    $scope.customer2 = {
      name: 'Joseph',
      address: '123 Fake St'
    };
  }])
  .directive('myCustomer', function($compile) {
    var getTemplate = function(attrs) {
      var isVip = attrs.type === "vip";
      return isVip
        ? "(VIP) Name: {{customer.name}} -- (VIP address hidden)"
        : "Name: {{customer.name}} -- Address: {{customer.address}}"
    };
  
    var linker = function(scope, element, attrs) {
      var template = getTemplate(attrs);
      element.html(template);
      $compile(element.contents())(scope);
    };
  
    return {
      restrict: 'E',
      link: linker,
      scope: {
        customer: '=info'
      }
    };
  });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="variableDirective">
  <div ng-controller="Controller">
    <my-customer type="regular" info="customer1"></my-customer>
    <br />
    <my-customer type="vip" info="customer2"></my-customer>
  </div>
</div>

但请注意,这是必要的,因为模板的编译发生在指令被实例化之后,因此您在指令定义时无法访问范围或属性。

您可以在这里找到更详细的解释和可重复使用的方法(我的示例所基于的方法):http://onehungrymind.com/angularjs-dynamic-templates/

【讨论】:

    猜你喜欢
    • 2014-08-18
    • 1970-01-01
    • 2016-10-28
    • 2015-02-12
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 2019-12-13
    相关资源
    最近更新 更多