Angular.js中的模板操作

时间:2014-05-01 22:08:13

标签: angularjs angularjs-directive

我试图在触发任何其他指令之前修改Angular模板,特别是插值。我是通过指令定义中的compile选项来完成的。

这是我的测试代码:

<!doctype html>
<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.js"></script>

    <script>
      angular.module('soQuestion', [])
        .directive('example', function () {
          return {

            compile: function (tElement, tAttrs) {
              if (tAttrs.foo && tAttrs.foo.match(/^keyword/)) {
                tElement.attr('foo', 'prefix-' + tAttrs.foo);
                console.log(tElement.attr('foo'));
              }
            }

          };
        })
        .controller('controller', function($scope) {
          $scope.value = 'something';
        });
    </script>
  </head>

  <body ng-app="soQuestion">
    <div ng-controller="controller">
        <div example foo="keyword_{{value}}"></div>
    </div>
  </body>

</html>

但是,即使<div foo="keyword_something"></div>功能被正确触发,我得到的最终结果是<div foo="prefix-keyword_something"></div>而不是compile。这是怎么回事?

2 个答案:

答案 0 :(得分:1)

这是一个指令优先问题,而且我还是不完全明白。但是不要因为{{}}本身就是一个指令。它会与你的某些顺序一起应用,并覆盖你的操作。如果它的终端和高优先级,它会清除。

DEMO

angular.module('soQuestion', [])
.directive('example', function () {
    return {
        priority: 1000,
        terminal : true,
        compile: function (tElement, tAttrs) {
            if (tAttrs.foo && tAttrs.foo.match(/^keyword/)) {
                tElement.attr('foo', 'prefix-' + tAttrs.foo);
                console.log(tElement.attr('foo'), tElement[0]);
            }
            return function(){};
        }

    };
})
.controller('controller', function($scope) {
    $scope.value = 'something';
});

因为这打破了{{}}我会考虑手动编译attr。

答案 1 :(得分:0)

angular.module('soQuestion', [])
    .directive('example', function () {
      return {

        compile: function (tElement, tAttrs) {
          if (tAttrs.foo && tAttrs.foo.match(/^keyword/)) {
            // Change the tAttrs hash instead of the element itself
            tAttrs.foo = 'prefix-' + tAttrs.foo;
            // Change the element too, in case no interpolation is present
            tElement.attr('foo', tAttrs.foo);
            console.log(tElement.attr('foo'));
          }
        }

      };
    })

说明:interpolate指令确实检查属性值的变化。但是它不再在DOM节点本身上查看,而是在tAttrs哈希上。


旧的悲观回答:

我认为不可能达到预期的效果。

查看Angular的源代码,collectDirectives将影响某个节点的指令列表放在一起。收集它们各自的compile函数,然后按优先级排序。问题是{{}}的编译函数然后绑定到keyword_{{value}}并且不受example指令的影响。