【问题标题】:AngularJS1 directive with `terminal:true` will disable rendering of expressions, why?带有 `terminal:true` 的 AngularJS1 指令将禁用表达式的呈现,为什么?
【发布时间】:2018-08-31 09:22:30
【问题描述】:

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')
        }
    }
})

请注意terminal 是true。

结果:

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

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

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

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

    所以使用表达式 {{}} 会导致添加指令。猜猜这就是它受“终止”属性影响的原因。

    【讨论】:

    • 我在myTerminal 指令中添加了priority: 0,以使其与“添加”的具有相同级别的优先级,但{{ hello }} 仍未呈现。
    • docs.angularjs.org/api/ng/service/$compile#-terminal- 请注意,指令模板中使用的表达式和其他指令也将被排除在执行之外。
    • 谢谢,文档中已注明,但我忽略了它。
    【解决方案2】:

    来自文档:

    终端

    如果设置为true,则当前priority 将是最后一组将执行的指令(当前priority 的任何指令仍将执行,因为同一priority 上的执行顺序未定义) . 请注意,指令模板中使用的表达式和其他指令也将被排除在执行之外。

    ——AngularJS Comprehensive Directive API Reference - terminal

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

    ngNonBindable

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

    ——AngularJS ng-non-bindable Directive API Reference

    【讨论】:

    • 感谢您将ngNonBindable 带到这里,这是一个很好的用例!
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2018-03-02
      • 1970-01-01
      • 2017-08-23
      • 2021-03-19
      • 1970-01-01
      • 1970-01-01
      • 2017-07-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多