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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带有`terminal:true`的AngularJS1指令会禁用表达式的渲染,为什么?相关的知识,希望对你有一定的参考价值。

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

答案

来自Docs:

terminal

如果设置为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

另一答案

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

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

另一答案

你需要使用ng-bind

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

DEMO

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>

以上是关于带有`terminal:true`的AngularJS1指令会禁用表达式的渲染,为什么?的主要内容,如果未能解决你的问题,请参考以下文章

带有 Html5Mode 的 Angular-UI-Router 刷新页面问题

apache上带有html5mode(true)的angularjs ngroute失败

为 withCredentials 指定 CORS 标头:true

Cookie 中的 Angular JWT 如何防止 CSRF/XSRF 和 XSS

带有包的java程序编译后无法在terminal下正常运行的解决

terminal--git bash