2

在发现指令时遇到以下问题:

<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 参数中检索它。”

所以它变成:

<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() 还是我看错了。

4

2 回答 2

4

这是我的两分钱。

这并不是说我们一定要从 HTML 中删除所有脚本调用,而是我们不想依赖 HTML 来使脚本工作。这样可以替换 HTML,并且我们知道管道(在本例中为 AngularJS)仍然可以工作。您不想从墙的角度(控制器、服务)引用任何需要了解 DOM(除了指令)的东西。

它创建了您的业务逻辑(然后可以进行测试)和您的视图(这几乎需要人工测试......直到人工智能变得更好)的清晰分离。

在某些情况下,例如单击事件,无法避免视图对底层脚本有一些了解,如果一个使用另一个它们是连接的。好处是在 Angular 方面,您只需要保持界面相同,并且可以更改实际实现而不会弄乱视图(它始终与界面有关,并且能够替换依赖项)。

基本上编写这个指令,所以它使用参数来潜在地扩展它的功能来调用任意函数,而不是将它绑定到只执行一项特定任务,这将避免复制和调整此代码的需要(不要重复自己,干)。

总而言之,解耦很重要,但始终需要了解相互协作的部分之间的接口。有时,避免代码重复的优势(因此,如果有问题/调整有很多地方需要更新)超过了将底层结构的任何知识隐藏在视图中的愿望。

请记住 addEventListener/attachEvent 仍然是这里发生的事情,请参阅 element.bind 调用,这仍然允许多个事件处理程序。

于 2013-07-10T23:30:51.847 回答
1

对于典型的网页来说,将 HTML 和应用程序逻辑解耦是一个好主意,其中 HTML 是由网页设计师编写的,然后通过添加一点点 JavaScript 来增强所产生的工作。

在到处创建具有复杂视图和表示逻辑的 SPA 时,您的大部分 HTML 都是由程序员编写的。Angular 为我们的程序员提供了带有默认指令的数据绑定功能,我认为使用它们是明智的。即使您将 HTML 和角度范围对象紧密结合在一起,Angular 也会在不存在的范围属性上静默失败。因此,在大多数情况下,如果存在不匹配,它不会造成大问题。

如果您偏执地认为您的 HTML 绑定不正确,我认为应该可以编写用于调试的角度服务,该服务将检查所有指令并在某些绑定绑定到未定义或空属性时警告您。

于 2013-07-11T10:10:03.267 回答