$ sce.trustAsHtml和ng-show

时间:2015-07-03 23:06:44

标签: javascript html angularjs ionic

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

我的离子应用程序中显示了几行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不起作用。如何让它按预期运行?

1 个答案:

答案 0 :(得分:2)

您遇到的当前问题是Angular正在按照您的意愿将您的文本视为HTML正确,但在执行此操作后,它不会像新的Angular模板一样绑定到新的属性和类。

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

请勿使用动态模板

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

使用指令

如果您要插入HTML的原因是为了重用HTML,那么您可能正在寻找的是指令,这是一个允许您完全执行此操作的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/