带有terminal:true的AngularJS1指令将禁用表达式的呈现,为什么?

时间:2018-08-31 09:22:30

标签: angularjs angularjs-directive

HTML代码:

<div ng-controller="MyController">
    <div>{{ hello }}</div>
    <div my-terminal>{{hello}}</div>
</div>

JS代码:

const app = angular.module('app', [])

app.controller('MyController', function ($scope) {
    $scope.hello = 'Hello, AngularJS'
})

app.directive('myTerminal', function () {
    return {
        restrict: 'A',
        terminal: true,
        link: function () {
            console.log('--- myTerminal')
        }
    }
})

请注意,terminaltrue

结果:

enter image description here

从angularjs文档中,我发现当terminaltrue时,将不会执行应用于优先级较低的同一元素的任何其他指令,但是我无法解释为什么<div my-terminal>{{hello}}</div>将不会呈现表达式{{hello}}

此问题的一个完整的小型演示:https://github.com/freewind-demos/angularjs1-directive-terminal-issue-demo

3 个答案:

答案 0 :(得分:3)

https://github.com/angular/angular.js/blob/master/src/ng/compile.js

function addTextInterpolateDirective(directives, text) {
      var interpolateFn = $interpolate(text, true);
      if (interpolateFn) {
        directives.push({
          priority: 0,
          compile: function textInterpolateCompileFn(templateNode) {
            var templateNodeParent = templateNode.parent(),
                hasCompileParent = !!templateNodeParent.length;
...

因此,使用表达式{{}}会导致添加指令。猜猜这就是为什么它会受到“终止”属性的影响。

答案 1 :(得分:2)

从文档中:

  

终端

     

如果设置为true,则当前priority将是将要执行的最后一组指令(当前priority处的任何指令仍将按照相同的执行顺序执行priority未定义)。 请注意,指令模板中使用的表达式和其他指令也将从执行中排除。

     

AngularJS Comprehensive Directive API Reference - terminal

使用ng-non-bindable属性的terminal文档会更好地解释其含义:

  

ngNonBindable

     

ngNonBindable指令告诉AngularJS不要编译或绑定当前DOM元素的内容,包括该元素本身上的优先级低于ngNonBindable的指令。如果该元素包含看似AngularJS指令和绑定但AngularJS应该忽略的元素,则这很有用。例如,如果您有一个显示代码片段的网站,就是这种情况。

     

AngularJS ng-non-bindable Directive API Reference

答案 2 :(得分:1)

您需要使用ng-bind

<div ng-controller="MyController">
  <div>{{hello}}</div>
  <div my-terminal ng-bind="hello"></div>
</div>

演示

const app = angular.module('app', [])

app.controller('MyController', function ($scope) {
    $scope.hello = 'Hello, AngularJS'
})

app.directive('myTerminal', function () {
    return {
        restrict: 'A',
        terminal: true,
        link: function () {
            console.log('--- myTerminal')
        }
    }
})
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="MyController">
    <div>{{ hello }}</div>
    <div my-terminal ng-bind="hello"></div>
</body>