我应该使用`this`或`$ scope`吗?


251

有两种用于访问控制器功能的模式: 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>

我个人发现,this.name与其他Java OO模式相比,它更容易上眼并且更自然。

请咨询?


使用“这”似乎是新的谷歌I / O 2013 m.youtube.com/watch?v=HCR7i5F5L8c:此外,还要检查这个答案stackoverflow.com/questions/11605917/...
AlanW

“ UserCtrl as uCtrl”语法是新的吗?我没有在1.0.6或1.1.4 ngController页面上看到它。
Mark Rajcok


1
为$范围,这说明最佳 codetunnel.io/angularjs-controller-as-or-scope
西

Answers:


229

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

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

两者都运行良好,唯一的错误答案是在没有明确原因的情况下将它们混合在同一应用中。坦白说,将它们混合会起作用,但只会增加混乱。因此,选择一个并滚动。最重要的是要保持一致。

哪一个?那取决于你。$ scope中还有更多示例,但是“ controller as”也在不断发展。这个比那个好吗?这值得商.。那么,您如何选择呢?

安慰

我更喜欢“ 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或watchs,尽管我尝试避免在控制器中监视),否则我也不需要这样做。

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


4
我个人也遵循您使用vm的方法。我了解到的唯一代码味道是,当您需要与$ scope进行专门交互时,例如,订阅或广播事件,访问控制器内部的表单验证变量等。这会导致混合环境,您仍然需要注入$ scope即使您将控制器用作功能。
Beyers

9
对。在这种情况下,$ scope仍用于,但更多地用作服务。当我们注入角度服务($ scope,$ q等)时,它们会提供我们需要的某些功能。$ scope允许我们监视,应用,使用消息以及数据绑定。即使使用控制器作为,$ scope仍然被使用,它只是被抽象化
John Papa 2013年

1
var vm = this;您是否也需要在视图中将其称为“ vm”?“作为虚拟机的控制器”。他们必须一样吗?
Javid 2014年

2
@JohnPapa-SideWaffle模板为什么不“返回虚拟机”;当使用控制器作为?
凯文

2
@Kevin控制器有效地充当了Ctor,因此已经返回了“ this”。
约翰·帕帕

68

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


40

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

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

更新

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


10
我认为我们首先需要了解新的“ UserCtrl as uCtrl”语法,然后才能说出我们认为更好的语法。
Mark Rajcok

我同意“将UserCtrl作为uCtrl”,这需要理解。我认为这是个坏主意,原因与此处的论点大部分相同:groups.google.com/forum
topic

4
如果您熟悉JS中的oop,那么这是很有意义的。控制器是一类,每次创建控制器时,angular都会使用新的运算符。欢迎您不喜欢它,但指出使用“ this”存在一些问题,这会产生误导。这是“ this”的可接受的用例。
MJ 2015年

$ scope不会增加任何清晰度。实际上,使用$ scope且嵌套了作用域时,很难知道视图中发生了什么。与语法一起使用的控制器增加了更多的清晰度。在视图中,方法或属性源自哪个控制器的作用域很清楚。
ddelrio1986

1
我同意@ ddelrio1986。刚刚遇到了引导选项卡和使用var vm = $ scope的问题。制表符有其自身的范围,因此您无法按预期使用它,但是在var vm = this的情况下,一切按预期进行。
user441521 '18


7

Angular文档明确告诉您this建议使用。那,除了$scope被删除的事实之外,这是我从不使用的充分理由$scope


4

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

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


2

我更喜欢组合。

在将一些模拟数据填充到$ 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可以用$来做一些有趣的事情。

“这个”直截了当,附加了双向绑定的数据和函数。您只会看到附件:

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;

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


1

两者都有效,但是如果将适用于范围的内容应用于$ scope,并且将适用于控制器的内容应用于控制器,则代码将易于维护。对于那些说“ U用示波器的人,请不要将此Controller当作语法”……它可能起到相同的作用,但是我不知道您如何能够维护一个庞大的应用程序而不会丢失任何东西。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.