Директива AngularJS1 с терминалом: true отключит рендеринг выражений, почему? - PullRequest
0 голосов
/ 31 августа 2018

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.

Результат:

enter image description here

Из документа angularjs, который я обнаружил, когда terminal равен true, любые другие директивы, примененные к тому же элементу с более низким приоритетом, не будут выполняться, но я не могу объяснить, почему <div my-terminal>{{hello}}</div> не будет отображать выражение {{hello}}

Небольшая полная демонстрация по этому вопросу: https://github.com/freewind-demos/angularjs1-directive-terminal-issue-demo

Ответы [ 3 ]

0 голосов
/ 31 августа 2018

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

0 голосов
/ 31 августа 2018

Из документов:

терминал

Если установлено значение true, то текущий priority будет последним набором директив, которые будут выполняться (любые директивы в текущем priority все равно будут выполняться, так как порядок выполнения для того же priority не определен) , Обратите внимание, что выражения и другие директивы, используемые в шаблоне директивы, также будут исключены из исполнения.

- Справочник по AngularJS API Reference - терминал

Лучшее объяснение того, что это значит, приведено в Документах для ng-non-bindable, в которых используется свойство terminal:

ngNonBindable

Директива ngNonBindable указывает AngularJS не компилировать или связывать содержимое текущего элемента DOM, включая директивы самого элемента, которые имеют более низкий приоритет, чем ngNonBindable. Это полезно, если элемент содержит то, что кажется директивами и привязками AngularJS, но которые должны игнорироваться AngularJS. Это может иметь место, например, если у вас есть сайт с фрагментами кода.

- Директива AngularJS ng-non-bindable API API

0 голосов
/ 31 августа 2018

Вам нужно использовать 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>
...