【问题标题】:HTML text binding in view(with trustAsHtml) from JSON, having ng-Class does not evaluate properly来自 JSON 的视图中的 HTML 文本绑定(使用 trustAsHtml),具有 ng-Class 无法正确评估
【发布时间】:2015-05-14 20:47:30
【问题描述】:

我有一个带有两个实心 div 的标题,一个在另一个之下。当我们滚动页面时,我在控制器中包含了动画来隐藏底部的 div。当我们向下滚动页面时,这个顶部的 DIV 也有一些变化。我在 ng-Class 中使用 smallHeader.floatItRightsmallHeader.floatItLeft 来控制它。正如您从 ss_header.html(指令模板)中看到的那样,具有 smallHeader.floatItRight 类的普通 div 可以完美运行,而来自 JSON 文件的 ng-Class 绑定中的“smallHeader.floatItRight”无法正常工作。对此有任何想法或想法吗?提前致谢。

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>",

具有指令的主要 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;}

【问题讨论】:

  • 我没有看到在您的示例代码中使用 JSON 内容“headerHtmlContent”的任何地方。在这里相关吗?
  • @shershen,是的!我在控制器中添加了一些内容。我从服务中获取“headerHtmlContent”并将其绑定到绑定到指令模板的范围变量 $scope.headerHTML。如果您需要对此进行更多说明,请告诉我。
  • 首先,检查generalServ.save() 承诺是否在您开始滚动时成功解决($scope.headerHTML 已定义)?您的代码中是否有任何实际错误?
  • 我的控制台没有出现任何错误。我的承诺已经兑现,我的 headerHTML 也很完美。
  • 我猜的问题是 - 来自 JSON 的 ng-Class。在开发人员工具中,当我看到 HTML 时,它是这样的:

    Coupons Clipped |您的储蓄:

    。当我滚动页面时,应该添加了 fright 类。但事实并非如此。而普通的
    是来自 JSON 的 not 绑定,它添加了“fright”类。

标签: angularjs angularjs-directive ng-class


【解决方案1】:

ng-bind-html 将不起作用,因为您的 html 中有指令和插值。 Angulars ngBindHtml 指令仅用于纯 html。在您的 ssHeader 指令中,您需要编译标头字符串。像这样就可以解决问题。

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服务的使用。在我继续之前,我想声明,在上面的 sn-p 中编写的指令中我们实际上并没有使用 compile 方法,我们可以直接使用 link 方法。

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

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

在以下情况下使用编译方法:

当我们需要在任何连接发生之前动态地操作指令的模板时,编译方法优于链接方法。在它变得“活着”之前。例如,如果我们想根据 urlTemplate 指令属性 &lt;my-directive template-url="/apath/my-cutom-template.html"&gt; 更改默认模板

【讨论】:

  • 能否在编译函数中给出cmets,把里面的代码解释一下,这样对别人也有好处?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-03
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多