为什么角度为在同一 DOM 元素上定义的指令定义“优先级”属性
Why does angular define "priority" property for directives that are defined on the same DOM element?
我发现 angular 没有利用定义指令的顺序,而是使用静态priority
字段。它并非适用于所有情况。
例:
<div ng-if="items.length < 50" ng-repeat="item in items"></div>
<div ng-repeat="item in items" ng-if="items.length > 50"></div>
这两行代码可能有不同的含义。
案例1)检查项目数量是否小于50,NG重复10000项目
案例 2) ng-重复 10000 个项目,然后在每个元素上检查项目数量是否小于 50
如果ng-if
具有更高的优先级,则第一行代码将允许显然非常重要的优化...
显然,与按定义顺序对指令进行优先级排序相比,使用静态"优先级"字段没有太多理由,所以我的问题是:
应该采取什么步骤来批准这个想法并加以实施?
(我从来没有研究过angularjs源代码,需要一些外部帮助来指出需要更改的地方才能提供主题方法,我将感谢在这个方向上的任何外部帮助)
提前谢谢你!
编辑
这是一个 jsFiddle 显示ng-if
对于 10000 个项目的数组执行了 20000 次,每个ng-if
都会创建一个范围,使问题加倍......
http://jsfiddle.net/u840t0dh/17/
我找不到为什么 angular 不利用定义指令的顺序的原因,而不是使用静态优先级字段,它不适合所有情况。
角度指令的想法是扩展浏览器内置的标记语言(标签,属性等)。我相信标准浏览器标记中没有这样的功能。我想强调的是,角度中的指令是声明式编程。
对于您指出的问题,在我看来,这就像是命令式编程。这就像您在页面中用if
和loop
编写逻辑一样。但是在您的情况下,在同一元素上使用它们没有多大意义=>这与在任何命令式编程语言(c ++,c#,java,...)中在同一行上编写if
和for loop
非常相似。如果你遵循命令式编程的思维方式,这样写会更有意义:
<div ng-if="items.length > 50">
<div ng-repeat="item in items"></div>
</div>
我同意有时为了编写 UI 渲染代码,我们必须编写有点像命令式编程,但它可以保持在最低限度。即使在这些情况下,如果你遵循命令式编程的思维方式(就像我指出的那样),也不应该有问题。
因此,您指出的问题可能是一个问题,但实际上与我们从声明性标记中获得的优势相比不是一个大问题。
声明式编程和命令式编程各有利弊:
- http://en.wikipedia.org/wiki/Declarative_programming
- https://softwareengineering.stackexchange.com/questions/32781/declarative-programming-vs-imperative-programming
对于扩展"标记"的指令的情况,声明式编程更有意义,这是角度指令的设计方式(标记实际上是声明性的)
声明式编程的重点是告诉你想要"什么",而不是"如何"去做。这样做的好处是:它更简单,更容易理解。
来自 MSDN
事实上,易于理解代码 — 即使在不熟悉的情况下 上下文 - 是声明式样式的主要优点之一。
声明式编程最显着的好处是程序 指定我们想要获得的"什么"作为结果,而不是"如何"。作为一个 结果,更重要的是了解我们的领域 使用语言的每个细节。
有了你的建议,更多的是关于你想"如何"完成一项任务。您的建议的缺点是,当我们使用指令时,我们需要了解它们在"内部"的工作方式。
例如:当你对同一个元素使用许多指令时,使用这些指令的人需要了解放置指令的顺序是什么(这应该是实现指令的人关心的问题)。这是声明式编程试图避免的事情,因为它对于指令的用户来说很复杂
为了回答您的问题,优先级有几个可能的用例。我并不是说它们很常见,但它们是可能的,而且可能非常强大......
下面是两个示例:
用例 A) 包装任何指令。
通过使用优先级,您可以在给定指令之前或之后运行自定义代码。假设您有一个包含数千个 ng-click 指令的现有角度应用程序,并希望在每次 ng-click 之前运行一些东西。你可以做这样的事情:
angular.module('app', [])
.directive('ngClick', function($rootScope) {
return {
restrict: 'A',
priority: 100,
link: function(scope, element, attr) {
element.bind('click', function(ev) {
alert("custom click running");
})
}
}
})
.controller('MyCtrl', function($scope) {
$scope.alert = function() {
alert('built-in click running!')
}
})
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js@1.0.7" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script>
</head>
<body ng-controller="MyCtrl">
<a ng-click="alert()">Click me</a>
</body>
</html>
在这里,您的自定义单击将在单击的角度构建之前运行。
用例 B) 终止执行
通过使用优先级和终端:true,可以阻止执行其他指令。例如,在所有删除操作上,您可以使用自定义指令来请求确认。在这种情况下,使用 DOM 定义的顺序将是危险的,因为您要删除记录。
var app = angular.module('terminal', []);
app.controller('MainCtrl', function($scope) {
$scope.deleteIt = function() {
window.alert('Delete called!');
}
});
app.directive('confirmationNeeded', function() {
return {
priority: 10,
terminal: true,
link: function(scope, element, attr) {
var msg = attr.confirmationNeeded || "Are you sure?";
var clickAction = attr.ngClick;
element.bind('click', function() {
if (window.confirm(msg)) {
scope.$eval(clickAction)
}
});
}
};
});
<!doctype html>
<html ng-app="terminal">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
</head>
<body ng-controller="MainCtrl">
<a href="#" ng-click="deleteIt(id)" confirmation-needed="Are you sure you want to Delete?">Delete with custom message</a>
</body>
</html>
- 用嵌套函数和默认函数定义函数
- Dojo不解析自定义小部件的模板html中的小部件声明性
- 为什么“;未定义的“;在JavaScript中结束循环
- 要求未定义JS回调参数
- 控制台返回var不是't定义,但它是
- 在自定义mean.io包中使用angular-chart.js作为依赖项
- 如何检查管道中未定义的项目
- TypeError:无法读取属性'推'未定义的JavaScript
- jQuery自定义验证比较多个输入的序列
- 查看JS对象的所有键,甚至是getter定义的键
- fetch() 函数未在 Ubuntu Chromium 浏览器上定义
- $window.ga在AngularJS事件中未定义
- 如何在JQuery函数中定义一个值,然后调用另一个函数并使用该值
- 是否有任何方法可以使用jQuery替换在数组中定义值的文本
- 未捕获的TypeError无法读取未定义的属性socialsharing
- 为什么角度为在同一 DOM 元素上定义的指令定义“优先级”属性
- 基于一个属性的自定义优先级对数组进行排序
- 在angularJS中根据自定义属性优先级向列表元素中添加类
- 如何在webpack中定义加载器的优先级
- Parsley js对验证约束和自定义错误消息进行优先级排序