253

有两种用于访问控制器功能的模式: this$scope.

我应该使用哪个以及何时使用?我了解this设置为控制器,并且$scope是视图范围链中的一个对象。但是使用新的“Controller as Var”语法,您可以轻松地使用其中任何一种。所以我要问的是什么是最好的,未来的方向是什么?

例子:

  1. 使用this

    function UserCtrl() {
      this.bye = function() { alert('....'); };
    }
    
    <body ng-controller='UserCtrl as uCtrl'>
      <button ng-click='uCtrl.bye()'>bye</button>
    
  2. 使用$scope

    function UserCtrl($scope) {
        $scope.bye = function () { alert('....'); };
    }
    
    <body ng-controller='UserCtrl'>
        <button ng-click='bye()'>bye</button>
    

与其他 Javascript OO 模式相比,我个人发现this.name它更容易看,更自然。

请指教?

4

8 回答 8

230

两者都有其用途。首先,一些历史...

$scope 是“经典”技术,而“controller as”是较新的技术(从正式版本 1.2.0 开始,尽管它确实出现在此之前的不稳定预发行版中)。

两者都工作得很好,唯一错误的答案是在没有明确原因的情况下将它们混合在同一个应用程序中。坦率地说,混合它们会起作用,但这只会增加混乱。所以选择一个并滚动它。最重要的是要保持一致。

哪一个?这取决于你。$scope 的例子还有很多,但“controller as”也开始流行起来。这个比那个好吗?这是值得商榷的。那么你如何选择呢?

舒适

我更喜欢“控制器为”,因为我喜欢隐藏 $scope 并通过中间对象将控制器中的成员暴露给视图。通过设置 this.*,我可以将我想从控制器公开的内容公开给视图。你也可以用 $scope 来做到这一点,我只是更喜欢使用标准的 JavaScript。事实上,我这样编码:

var vm = this;

vm.title = 'some title';
vm.saveData = function(){ ... } ;

return vm;

这对我来说感觉更干净,并且可以很容易地看到暴露在视图中的内容。请注意,我将返回的变量命名为“vm”,它代表 viewmodel。这只是我的约定。

使用 $scope 我可以做同样的事情,所以我不会增加或减少这项技术。

$scope.title = 'some title';
$scope.saveData = function() { ... };

所以这取决于你。

注射

使用 $scope 我确实需要将 $scope 注入控制器。我不必对控制器执行此操作,除非我出于其他原因需要它(例如 $broadcast 或手表,尽管我尽量避免在控制器中使用手表)。

更新 我写了这篇关于两个选择的帖子:http: //www.johnpapa.net/do-you-like-your-angular-controllers-with-or-without-sugar/

于 2013-11-12T21:43:22.297 回答
68

$scope在 Angular 2.0 中被删除。因此,this随着 Angular 2.0 的发布日期越来越近,使用将是其他人想要遵循的一种方法。

于 2015-01-21T04:09:34.157 回答
40

我的观点是 javascript 中的“this”本身就有足够的问题,并且为其添加另一个含义/使用不是一个好主意。

为了清楚起见,我会使用 $scope。

更新

现在有 'controller as' 语法,在这里讨论。我不是粉丝,但现在它是一个更“官方”的 AngularJS 构造,它值得关注。

于 2013-05-18T01:59:03.920 回答
11

我认为 Controller As 更好,因为它允许更轻松地嵌套范围,如 Todd Motto 所述:

http://toddmotto.com/digging-into-angulars-controller-as-syntax/

此外,它将确保您始终拥有至少一个 . 在您的绑定表达式中,这迫使您遵循不绑定到原语建议。

另外,您可以从 2.0 中消失的范围中解耦。

于 2015-02-03T16:25:14.107 回答
7

Angular 文档明确告诉您this建议使用。$scope除了被删除的事实之外,还有足够的理由让我从不使用$scope.

于 2015-12-09T19:48:52.460 回答
4

jason328 的“$scope 正在 Angular 2.0 中被删除”对我来说是一个很好的理由。我找到了另一个帮助我做出选择的理由:this更具可读性——当我看到fooCtrl.barHTML 时,我立即知道在哪里可以找到bar.

更新:切换到解决方案后不久this,我开始想念$scope需要更少打字的方式

于 2015-08-27T07:55:59.260 回答
3

我更喜欢组合。

在用一些模拟数据填充它们之后,一个简单的 $scope 和 'this' 的 console.log 会告诉你这一点。

$scope 允许访问控制器的底层部分,例如:

$$ChildScope: null;
$$childHead: null;
$$childTail: null;
$$listenerCount: Object;
$$listeners: Object;
$$nextSibling: Scope;
$$prevSibling: null;
$$watchers: null;
$$watcherCount: 0;
$id: 2;
$parent: Object;
foo: 'bar';

** Angular 团队不建议使用 $$ 的属性和方法,但是 $ 可以安全地使用 $parent 和 $id 做一些很酷的事情。

'this' 直截了当,附加了 2-way-bound 数据和函数。您只会看到您附加的内容:

foo: 'bar';

那么为什么我更喜欢组合呢?

在 ui-router 嵌套应用程序中,我可以访问主控制器,在子控制器中设置和调用通用值和函数:

在主控制器中:

// Main Controller
var mainCtrl = this;
mainCtrl.foo = 'Parent at the bar';

在子控制器中:

// Child Controller
var mainCtrl = $scope.$parent.mainCtrl;
var childCtrl = this;

// update the parent from within the child
childCtrl.underageDrinking = function(){
    mainCtrl.foo = 'Child at the bar';
}

// And then attach the child back to a property on the parent controller!
mainCtrl.currentCtrl = childCtrl;

现在,您可以从子内部访问父级,从父级访问子级!

于 2017-01-28T18:43:21.740 回答
1

两者都有效,但是如果您将适用于范围的东西应用到 $scope,并且如果您将适用于控制器的东西应用到控制器,那么您的代码将很容易维护。对于那些说“呃,只是使用范围忘记这个控制器作为语法”的人......它可能工作相同,但我想知道你如何能够维护一个巨大的应用程序而不会失去对事物的跟踪。

于 2014-01-23T17:14:12.843 回答