真的,这一切都归结为您的视图代码必须以某种方式连接到您的应用程序逻辑中。 AngularJS 的最佳实践通常表明您应该编写自己的模型(代表您的业务领域的对象)并将它们附加到范围。想象一下这样的代码:
<img ng-src="{{img}}" ng-click="myProfile.setMainImage(img)">
myApp.controller("ProfileController", function($scope, myProfile) {
$scope.myProfile = myProfile;
});
视图显示“当单击此图像时,它将在 myProfile 上调用 setMainImage()。”业务逻辑在myProfile里面,可以测试等等。视图只是一个钩子。
在更“传统”或“普通”的 jQuery 设置中,您必须编写如下内容:
$("#someId img").on('click', function() {
var img = $(this).attr('src');
myProfile.setMainImage(img); // where does myProfile come from here?
// how does it update the view?
});
当然,JavaScript 社区已经确定以这种方式编写大型应用程序并不真正站得住脚,部分原因是视图和模型对象之间的脱节(如代码 sn-p 中的 cmets 所示) ,这就是为什么我们首先拥有像 Angular 这样的框架。
所以,我们知道这个原生 jQuery 代码并不理想,但我们仍然不确定整个 ngClick 的事情。让我们将它与另一个非常流行的提供 MV* 架构的 JavaScript 框架 Backbone 进行比较。在最近关于 AngularJS 的 RailsCasts 节目中,someone asked a very similar question:
只是我,还是 AngularJS 看起来很糟糕? Ryan,不要误会我的意思,这一集很棒,但我不相信这个框架。
所有ng-show、ng-repeat、ng-class 看起来都像旧的 Java 的 JSF 和类似的框架。它还使用 ng-submit 和 ng-click 强制执行突兀的 JS。
所以我的观点是:你的观点很容易变得混乱并完全依赖它。其他框架(如 Backbone)的优点是在表示和行为(较少或没有依赖关系)和结构化客户端应用程序 (MVVM) 之间分离了关注点。
My response 也适用于这里:
在像 Backbone 这样的框架中,您会得到类似以下代码(取自 Backbone 网站,减去几行代码):
var DocumentView = Backbone.View.extend({
events: {
"dblclick" : "open",
"click .icon.doc" : "select",
"contextmenu .icon.doc" : "showMenu",
"click .show_notes" : "toggleNotes",
"click .title .lock" : "editAccessLevel",
"mouseover .title .date" : "showTooltip"
},
open: function() {
window.open(this.model.get("viewer_url"));
},
select: function() {
this.model.set({selected: true});
},
});
在这个对象这是一个视图中,您正在为各种元素设置事件处理程序。这些事件处理程序调用视图对象上的函数,这些函数委托给模型。您还可以在各种模型事件(例如change)上设置回调,然后调用视图对象上的函数来相应地更新视图。
在 Angular 中,DOM 是您的视图。当使用ng-click、ng-submit 等时,您将在这些元素上设置事件处理程序,这些处理程序调用应该委托给模型对象的函数。使用 ng-show、ng-repeat 等时,您正在为更改视图的模型事件设置回调。
AngularJS 在幕后为您设置这些 [钩子和] 回调的事实是无关紧要的;这与 Backbone 之类的东西的唯一区别是 Angular 允许您以声明方式编写视图——你描述你的视图 是什么——而不是命令式地——描述你的视图 做什么 em>。
所以,最后,<a ng-click="model.set({selected: true})"> 添加的依赖项实际上并不比
events: {
'click a': 'select'
},
select: function() {
this.model.set({selected: true});
}
...但它肯定是少了很多代码。 ;)
(注意:实际上,Angular 版本应该是<a ng-click="select()">,作用域上的select 方法就像Backbone 示例中视图中的select 方法。)
现在,也许一个合法 担心是您不喜欢标记中的事件挂钩。就个人而言,我非常喜欢 Angular 视图的声明性,其中您的标记描述 视图是什么,并且您在事件(无论是用户生成的还是模型中的简单更改)和您的事件之间有两种绑定方式视图——我发现我编写的用于连接事件的样板代码要少得多(尤其是由模型更改驱动的视图更改),而且我认为总体上对视图进行推理更容易。