角度';s在HTML属性中使用内联JavaScript不是;坏习惯;?

角度';s在HTML属性中使用内联JavaScript不是;坏习惯;?,javascript,angularjs,Javascript,Angularjs,当我阅读Angular教程时,我真的很喜欢它,但是“ng click”不是等同于内联onClick吗?我的理解是,JavaScript社区认为HTML中的内联JavaScript事件处理程序是“糟糕的做法” 如果知道为什么在使用Angular时不再认为这是“不正确的”,那就太好了 来源:实际上,这一切都归结于这样一个事实:视图代码必须以某种方式连接到应用程序逻辑中。AngularJS的最佳实践通常表明,您应该编写自己的模型——表示业务领域的对象——并将它们附加到范围中。想象一下这样的代码:

当我阅读Angular教程时,我真的很喜欢它,但是“ng click”不是等同于内联onClick吗?我的理解是,JavaScript社区认为HTML中的内联JavaScript事件处理程序是“糟糕的做法”


如果知道为什么在使用Angular时不再认为这是“不正确的”,那就太好了


来源:

实际上,这一切都归结于这样一个事实:视图代码必须以某种方式连接到应用程序逻辑中。AngularJS的最佳实践通常表明,您应该编写自己的模型——表示业务领域的对象——并将它们附加到范围中。想象一下这样的代码:


myApp.controller(“ProfileController”,函数($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社区已经确定,以这种方式编写大型应用程序实际上是站不住脚的,部分原因是视图和模型对象之间的断开连接(如代码片段中的注释所示),这就是为什么我们首先使用Angular之类的框架

因此,我们知道这个原生jQuery代码并不理想,但我们仍然不能确定整个
ngClick
的内容。让我们将其与另一个非常流行的JavaScript框架进行比较,后者提供了一个MV*体系结构,即主干。在最近关于AngularJS的Railscapsts插曲中:

是我,还是安格拉斯看起来是个坏主意?Ryan,别误会,这一集很棒,但我不相信这个框架

所有的
ng show
ng repeat
ng class
看起来都像旧Java的JSF和类似的框架。它还通过
ng submit
ng click
强制执行突兀的JS

所以我的观点是:你的观点很容易变得杂乱无章,完全依赖于它。其他框架(如主干网)的优点是在表示和行为(较少或无依赖性)之间分离关注点,以及结构化客户端应用程序(MVVM)

也适用于以下情况:

在像主干网这样的框架中,您会有如下代码(取自主干网网站,减去几行):

在这个视图对象中,您正在各种元素上设置事件处理程序。这些事件处理程序调用视图对象上的函数,这些函数将委托给模型。您还可以对各种模型事件(例如
change
)设置回调,这些事件反过来调用视图对象上的函数来相应地更新视图

在Angular中,DOM是您的视图。使用
ng click
ng submit
等时,您正在这些元素上设置事件处理程序,这些元素调用应委托给模型对象的函数。使用
ng show
ng repeat
等时,您正在设置更改视图的模型事件回调

AngularJS在幕后为您设置这些[挂钩和]回调的事实是无关紧要的;这与主干之类的东西的唯一区别是Angular让你以声明的方式写你的视图——你描述你的视图是什么——而不是强制性地描述你的视图是什么

因此,最后,
实际上并没有增加更多的依赖项

events: {
  'click a': 'select'
},

select: function() {
  this.model.set({selected: true});
}
…但它确实少了很多代码。;)

(注意:实际上,角度版本应该是
,范围上的
select
方法与主干示例视图中的
select
方法类似。)


现在,一个合理的担忧可能是您不喜欢标记中的事件挂钩。就我个人而言,我非常喜欢Angular视图的声明性,您的标记描述了视图是什么,事件(无论是用户生成的还是模型中的简单更改)和视图之间有双向绑定——我发现我编写的连接事件的样板代码要少得多(尤其是由模型更改驱动的视图更改),并且我认为从总体上讲,对视图进行推理更容易。

我个人不喜欢任何内联内容,也会避免类似的内容,尽管这是一个意见问题。理论上,如果有人使用内联,如果代码仍然有效,我想有人可以使用它。如果是我,我会避免任何HTML定义的内联事件。我从来没有这样做过使用angularjs,但它看起来像一个模板框架,所以我必须仔细查看才能确定。如果它是在HTML上呈现的,它可能有或可能没有“ng click”属性,您确定它确实是内联的,还是它创建了一个JS,在“生成”模板时绑定事件?虽然我对Angularjs不太熟悉,但它可能只是内联事件,但据说它是为你做模板的,这可能是人们想要使用它的原因(尽管我个人认为我不喜欢那个库,再次,意见问题,所以ppl可能会否决这个问题)。它实际上不是内联的。将属性的内容设置为
setImage(img)
实际上不会执行绑定。解析模板的脚本将执行绑定。非常类似的问题:AngularJS(和ReactJS)是将静态数据层(HTML)与逻辑(javascript)耦合在一起的引人注目的javascript框架需要处理这些数据。这是一种糟糕的做法。你实际上是在将开发者锁定在谷歌(或Facebook)产品中。例如:你花了两年时间编写AngularJS应用程序,现在你想转向ReactJS,因为它具有更快的性能。如果你已经将逻辑与数据解耦,你就可以
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});
  },

});
events: {
  'click a': 'select'
},

select: function() {
  this.model.set({selected: true});
}