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

AngularJS1 directive with `terminal:true` will disable rendering of expressions, why?

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

结果:

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

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

您需要使用 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>

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;
...

所以使用表达式 {{}} 会导致添加指令。猜猜这就是为什么它受到 'terminate' 属性.

的影响

来自文档:

terminal

If set to true then the current priority will be the last set of directives which will execute (any directives at the current priority will still execute as the order of execution on same priority is undefined). Note that expressions and other directives used in the directive's template will also be excluded from execution.

AngularJS Comprehensive Directive API Reference - terminal

ng-non-bindable 的文档更好地解释了这意味着什么,它使用 terminal 属性:

ngNonBindable

The ngNonBindable directive tells AngularJS not to compile or bind the contents of the current DOM element, including directives on the element itself that have a lower priority than ngNonBindable. This is useful if the element contains what appears to be AngularJS directives and bindings but which should be ignored by AngularJS. This could be the case if you have a site that displays snippets of code, for instance.

AngularJS ng-non-bindable Directive API Reference