在发现指令时遇到以下问题:
<div ng-app="twitterApp">
<div ng-controller="AppCtrl">
<div enter>Roll over to load more tweets</div>
</div>
</div>
var app = angular.module('twitterApp', []);
app.controller("AppCtrl", function ($scope) {
$scope.loadMoreTweets = function () {
alert("Loading tweets!");
}
})
app.directive("enter", function () {
return function (scope, element, attrs) {
element.bind("mouseenter", function () {
scope.loadMoreTweets();
})
}
})
他们说: “最好通过将loadMoreTweets()方法作为视图中的字符串参数传递给指令,然后从指令中的attrs参数中检索它来完全解耦loadMoreTweets()方法。”
所以它变成了:
<div ng-app="twitterApp">
<div ng-controller="AppCtrl">
div enter="loadMoreTweets()">Roll over to load more tweets</div>
</div>
</div>
app.directive("enter", function () {
return function (scope, element, attrs) {
element.bind("mouseenter", function () {
scope.$apply(attrs.enter);
})
}
})
但是不会回到:
**<div onClick="loadMoreTweets()">Roll over to load more tweets</div>**
这让我感到困惑,这样JavaScript再次与HTML混合在一起。我们不是想避免这种情况吗?我们今天使用addEventListener()和attachEvent(),或者我看错了。
答案 0 :(得分:4)
这是我的两分钱。
我们并不是要尝试从HTML中删除所有脚本调用,而是我们不希望依赖HTML来使脚本工作。通过这种方式可以替换HTML,我们知道管道(在这种情况下是AngularJS)仍然可以工作。您不希望从墙的角度侧(控制器,服务)引用任何需要DOM知识的指令(除了指令)。
它创建了一个明确的业务逻辑分离(可以进行测试)和您的视图(非常需要人工测试......直到AI变得更好)。
有一些情况,例如click事件,如果一个人使用另一个连接的话,就不会避免让视图对底层脚本有所了解。好的方面是在Angular方面,你只需要保持你的界面相同,你可以改变实际的实现而不会弄乱视图(它总是关于接口并且能够替换依赖关系)。
基本上编写这个指令,所以它使用参数来扩展它的功能来调用任意函数而不是将它绑定到只执行一个特定任务将避免复制和调整这个代码的需要(不要重复自己,干)
它的长短不一致是非常重要的,但是对于相互作用的部件之间的接口的一些了解总是必要的。有时避免代码重复的优势(因此,如果出现问题/调整,很多地方需要更新)超出了保持对视图隐藏任何基础结构知识的愿望。
请记住,addEventListener / attachEvent仍然是这里发生的事情,请参阅element.bind调用,这仍然允许多个事件处理程序。
答案 1 :(得分:1)
将HTML和应用程序逻辑分离对于典型的网页来说是一个好主意,其中HTML是由网页设计师编写的,然后通过添加少量JavaScript来增强所得到的工作。
在创建具有复杂视图和表示逻辑的SPA时,大多数HTML都是由程序员编写的。 Angular提供了数据绑定功能和默认指令供我们程序员使用,我认为使用它们是明智的。即使将HTML和角度范围对象紧密地结合在一起,Angular也会在不存在的范围属性上无声地失败。因此,在大多数情况下,如果存在不匹配,则不会造成大问题。
如果您对HTML绑定不正确感到偏执,我认为应该可以为调试编写角度服务,这将检查所有指令并警告您是否某些绑定绑定到undefined或null属性。