HTML 来自 JSON 的视图(使用 trustAsHtml)中的文本绑定,ng-Class 无法正确评估

HTML text binding in view(with trustAsHtml) from JSON, having ng-Class does not evaluate properly

我有一个 header 有两个固体 div 一个在另一个下面。当我们滚动页面时,我在我的控制器中加入了动画来隐藏底部 div。当我们向下滚动页面时,这个顶部 DIV 也有一些变化。我用 smallHeader.floatItRight 和 ng-Class 中的 smallHeader.floatItLeft 控制它。正如您从 ss_header.html(指令模板)中看到的那样,具有 class smallHeader.floatItRight 的普通 div 可以完美工作,而 ng-Class 中的 'smallHeader.floatItRight'来自 JSON 文件的绑定无法正常工作。对此有什么想法或想法吗?提前致谢。

JSON 文件有这个键和对应的值:

"headerHtmlContent":"<p class=\"coupons-text\" data-ng-class=\"smallHeader.floatItRight\">{{clippedCoupons}} Coupons Clipped | Your Savings:</p><p class=\"printable-text\">Printable | <a href=\"#\" class=\"disable-text\" data-ng-class=\"smallHeader.floatItLeft\">Direct2Card</a></p></div>",

Main HTML 具有指令:

 <ss-header styles="smallHeader" show="showHeader" header="headerHTML"></ss-header>

Directive.js:

myApp.directive("ssHeader", ['$compile', function($compile) {
  return {
    restrict: "E", //directive for element only 
    //replace: true, //replace the custom tag
    scope:{
        show:'=show',
        headerHTML: '=header',
        smallHeader: '=styles'
    }, 
    templateUrl: 'common/header/ss_header.html',
  }
}]);

指令HTML模板:

<!--BINDING FROM JSON-->
    <header data-ng-show="show" class="ss-header" data-ng-bind-html="headerHTML|convertAsHtml">
    </header>
<!--NORMAL DIV WHERE NG-CLASS WORKS-->
    <div data-ng-class="smallHeader.floatItRight">Sample DIV to show smallHeader.floatItRight works!!</div>

控制器:

angular.element($window).bind("scroll", function() {
            var scrollPos = $(this).scrollTop();
            if(scrollPos > previousTop){
               $scope.fadeAnimation = true;
               $scope.smallHeader = {
                    floatItRight: "fright",
                    floatItLeft: "fleft"
               }
            }
            else
                $scope.fadeAnimation = false;
            previousTop = scrollPos;
            $scope.$apply();        
        });

var generalServ = new fetchServiceData($service.api.SS_RESP);

    generalServ.save().$promise.then(function(response){

        $scope.headerHTML = $interpolate(response.en_US.siteLayout.headerHtmlContent)($scope);

    },function(err){
        console.log('error in fetching service data')
    });

styles.css

.fleft{float:left;}
.fright{float:right;}

.coupons-text.fright{float:right;}
.disable-text.fleft{float:left;}

ng-bind-html 将不起作用,因为您在 html 中有指令和插值。 Angulars ngBindHtml 指令仅用于普通 html。在您的 ssHeader 指令中,您需要编译 header 字符串。像这样的东西就可以了。

angular.module('MyApp', [])
  .controller('MyController', ['$scope',
    function($scope) {
      $scope.showHeader = true;
      $scope.smallHeader = {
        'fleft': false,
        'fright': false,
      };
      $scope.headerHTML = "<p class=\"coupons-text\" data-ng-class=\"styles\">{{clippedCoupons}} Coupons Clipped | Your Savings:</p><p class=\"printable-text\">Printable | <a href=\"#\" class=\"disable-text\" data-ng-class=\"styles\">Direct2Card</a></p></div>";
    }
  ])
  .directive("ssHeader", ['$compile', '$parse',
    function($compile, $parse) {
      return {
        restrict: "E",
        scope: {
          show: '=',
          header: '=',
          styles: '='
        },
        templateUrl: 'common/header/ss_header.html',
        compile: function compile(tElement, tAttrs, transclude) {

          return function postLink(scope, element, attrs, controller) {
            var headerElement = element.find('header');
            scope.$watch(attrs.header, function(html) {
              headerElement.html(html);
              $compile(headerElement.contents())(scope);
            });
            headerElement.html(scope.header);
            $compile(headerElement.contents())(scope);
          };
        }
      }
    }
  ]);
.fleft {
  float: left;
}
.fright {
  float: right;
}
.coupons-text.fright {
  float: right;
}
.disable-text.fleft {
  float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp" ng-controller="MyController">
  <label>float right <input type="checkbox" ng-model="smallHeader.fright" /></label>
  <label>float left <input type="checkbox" ng-model="smallHeader.fleft" /></label>
  
  <ss-header styles="smallHeader" show="showHeader" header="headerHTML"></ss-header>

  <script type="text/ng-template" id="common/header/ss_header.html">
    <div>
      <header data-ng-show="show" class="ss-header">
      </header>
      <!--NORMAL DIV WHERE NG-CLASS WORKS-->
      <div data-ng-class="styles">Sample DIV to show smallHeader.floatItRight works!!</div>
    </div>
  </script>
</div>

更新: 如果可以的话,我将尝试解释编译功能和 $compile 服务的使用。在继续之前,我想声明在上面代码片段中编写的指令中 我们实际上并没有使用编译方法 ,我们本可以使用 link方法直接。

在以下情况下使用 $compile 服务:

一般来说,我们使用 $compile 服务来编译一个 html 片段,其中包含针对给定范围的指令和 angular 内容,使其“alive”。然后我们将编译后的 html 放在我们需要的地方。在这种情况下,我们针对仅在 link 方法中可用的主机指令范围编译 html 片段(请参阅 postLink 函数),然后我们使用 jQLite 将其放入 header 元素中。

使用编译方法时:

当我们需要在任何连接发生之前动态地操作指令的模板时,compile 方法优于 link 方法。在它变成 "alive" 之前。例如,如果我们想根据 urlTemplate 指令属性 <my-directive template-url="/apath/my-cutom-template.html">

更改默认模板