Angular在HTML属性中使用Inline JavaScript并不是“坏习惯”?

当我通过Angular教程阅读时,我非常喜欢它,但是不是“ng-click”的onClick相当于onClick? 我的理解是,JavaScript社区已经确定HTML中的内联JavaScript事件处理程序是“不好的做法”。

<img ng-src="{{img}}" ng-click="setImage(img)"> 

如果知道为什么在使用Angular时不再认为“不正确”,那将是非常好的。

资料来源: http : //docs.angularjs.org/tutorial/step_10

真的,这一切都归结为您的视图代码必须以某种方式挂钩到您的应用程序逻辑。 AngularJS的最佳实践通常声明,您应该编写自己的模型(代表您的业务领域的对象),并将其附加到范围。 想象一下这样的代码:

 <img ng-src="{{img}}" ng-click="myProfile.setMainImage(img)"> 
 myApp.controller("ProfileController", function($scope, myProfile) { $scope.myProfile = myProfile; }); 

该视图说:“当这个图像被点击时,它会调用myProfile上的setMainImage()。” 业务逻辑位于myProfile内部,可以在其中进行testing等。视图只是一个钩子。

在一个更“传统”或“香草”的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社区已经确定,以这种方式编写大型应用程序并不是真正成立的,部分原因是视图和模型对象之间的断开(如代码片段中的注释所示),这就是为什么我们首先有像Angular这样的框架。

所以,我们知道这个原生jQuery代码并不理想,但我们仍然不确定整个ngClick事情。 让我们把它与另一个非常受欢迎的JavaScript框架进行比较,该框架提供了一个MV *架构,骨干。 在AngularJS最近的一个RailsCasts插曲中, 有人问了一个非常类似的问题 :

只是我,还是AngularJS看起来这么糟糕的主意? 瑞恩,不要误解我的意思,这个情节很棒,但是我不相信这个框架。

所有的ng-showng-repeatng-class看起来都像旧的Java的JSF和类似的框架。 它还通过ng-submitng-click强制执行JS。

所以我的观点是:你的观点很容易变得混乱,完全依赖它。 像Backbone这样的其他框架的优点是在performance和行为(较less或不依赖)和结构化客户端应用程序(MVVM)之间有一个分离关系。

我的回答也适用于此:

在像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 )上设置callback,然后调用视图对象上的函数来相应地更新视图。

在Angular中,DOM是你的看法。 当使用ng-clickng-submit等的时候,你要在这些元素上设置事件处理程序,这些元素调用应该委派给模型对象的函数。 在使用ng-showng-repeat等时,您正在对模型事件设置callback,以更改视图。

AngularJS在你背后为这些[钩子和callback]设置的事实是无关紧要的。 这个和Backbone之间的唯一区别是,Angular允许你声明式地写你的视图 – 你描述你的视图什么 – 而不是命令性的 – 描述你的视图。

所以,最后, <a ng-click="model.set({selected: true})">实际上不会增加​​更多的依赖

 events: { 'click a': 'select' }, select: function() { this.model.set({selected: true}); } 

…但它确实是一个更less的代码地狱。 ;)

(注意:实际上,Angular版本应该是<a ng-click="select()"> ,而范围上的select方法就像Backbone示例中视图中的select方法)。

现在,或许一个合理的问题是,你不喜欢你的标记中的事件挂钩。 就我个人而言,我非常喜欢Angular的视图的声明性质,你的标记描述了视图是什么 ,你有两种方式绑定事件(无论是用户生成的还是简单地改变模型)和你的意见 – 我发现我写更less的样板代码来连接事件(特别是模型中变化所导致的视图变化),而且我认为总体上来看这个视图更容易推理。