带有 `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')
}
}
})
请注意 terminal
是 true
。
结果:
从angularjs文档中,我发现当terminal
是true
时,任何其他应用在同一元素上的优先级较低的指令都不会被执行,但我无法解释为什么 <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.
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
时,任何其他应用在同一元素上的优先级较低的指令都不会被执行,但我无法解释为什么 <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 currentpriority
will be the last set of directives which will execute (any directives at the currentpriority
will still execute as the order of execution on samepriority
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 thanngNonBindable
. 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.