在AngularJS主页的“创建组件”部分,有这样一个例子:

controller: function($scope, $element) {
  var panes = $scope.panes = [];
  $scope.select = function(pane) {
    angular.forEach(panes, function(pane) {
      pane.selected = false;
    });
    pane.selected = true;
  }
  this.addPane = function(pane) {
    if (panes.length == 0) $scope.select(pane);
    panes.push(pane);
  }
}

注意select方法是如何添加到$scope的,而addPane方法是添加到this的。如果我把它改成$scope。addPane,代码崩溃。

文档说实际上是有区别的,但它没有提到区别是什么:

以前的Angular版本(1.0 RC之前)允许你将此方法与$scope方法互换使用,但现在不再是这样了。在作用域上定义的方法内部this和$scope是可以互换的(angular将this设置为$scope),但在控制器构造函数内部则不能互换。

this和$scope在AngularJS控制器中是如何工作的?


当前回答

在本课程(https://www.codeschool.com/courses/shaping-up-with-angular-js)中,他们解释了如何使用“this”和许多其他东西。

如果你通过"this"方法向控制器添加方法,你必须在视图中用控制器名"dot"你的属性或方法来调用它。

例如,在视图中使用控制器,你可能会有这样的代码:

    <div data-ng-controller="YourController as aliasOfYourController">

       Your first pane is {{aliasOfYourController.panes[0]}}

    </div>

其他回答

我刚刚读了一篇关于两者区别的非常有趣的解释,而且越来越多的人倾向于将模型附加到控制器上,并通过别名将控制器绑定到视图上。http://toddmotto.com/digging-into-angulars-controller-as-syntax/是文章。

注意:原始链接仍然存在,但格式的变化使其难以阅读。在原版中更容易看到。

他没有提到,但是在定义指令时,如果你需要在多个指令之间共享一些东西,并且不想要一个服务(在某些情况下,服务是一个麻烦),那么将数据附加到父指令的控制器上。

$scope服务提供了很多有用的东西,$watch是最明显的,但如果您需要将数据绑定到视图,那么在模板中使用普通控制器和“controller as”是很好的,而且可以说是更可取的。

在本课程(https://www.codeschool.com/courses/shaping-up-with-angular-js)中,他们解释了如何使用“this”和许多其他东西。

如果你通过"this"方法向控制器添加方法,你必须在视图中用控制器名"dot"你的属性或方法来调用它。

例如,在视图中使用控制器,你可能会有这样的代码:

    <div data-ng-controller="YourController as aliasOfYourController">

       Your first pane is {{aliasOfYourController.panes[0]}}

    </div>

我建议你阅读下面的帖子: "Controller as"还是"$scope"?

它很好地描述了使用“Controller as”公开变量而不是“$scope”的优点。

我知道你特别问了关于方法而不是变量的问题,但我认为最好坚持一种技术并与之保持一致。

所以在我看来,由于文章中讨论的变量问题,最好只使用“Controller as”技术,并将其应用于方法。

以前的Angular版本(1.0 RC之前)允许你使用这个 可以与$scope方法互换,但这不再是 的情况。在作用域this和$scope上定义的方法内部 可互换(angular将其设置为$scope),否则就不行 在你的控制器构造函数中。

要恢复这种行为(有人知道为什么改变吗?)你可以添加:

return angular.extend($scope, this);

在控制器函数的末尾(假设$scope被注入到这个控制器函数中)。

这有一个很好的效果,可以通过控制器对象访问父作用域,你可以在child中使用require: '^myParentDirective'

addPane被赋值给它的原因是<pane>指令。

窗格指令确实需要:'^tabs',它将来自父指令的tabs控制器对象放到link函数中。

addPane被赋值给它,以便窗格链接函数可以看到它。然后在窗格链接函数中,addPane只是选项卡控制器的一个属性,它就是tabscontrollerobject。addPane。因此,pane指令的链接函数可以访问tabs控制器对象,从而访问addPane方法。

我希望我的解释足够清楚。这很难解释。