【问题标题】:Should I use `this` or `$scope`?我应该使用 `this` 还是 `$scope`?
【发布时间】:2013-05-13 06:04:42
【问题描述】:

有两种模式用于访问控制器功能: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 与其他 Javascript OO 模式相比更直观、更自然。

请指教?

【问题讨论】:

标签: angularjs


【解决方案1】:

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

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

更新

现在有“控制器作为”语法,讨论过here。我不是粉丝,但现在它是一个更“官方”的 AngularJS 构造,它值得关注。

【讨论】:

  • 我认为我们首先需要了解新的“UserCtrl as uCtrl”语法,然后才能说出我们认为哪个更好。
  • Re 'UserCtrl as uCtrl',我同意,这需要理解。我认为这是一个坏主意,原因与此处提出的大多数原因相同:groups.google.com/forum/#!topic/angular/84selECbp1I
  • 如果您熟悉oop in JS,那非常有意义。控制器是一个类,每次创建控制器时,Angular 都会使用 new 运算符。欢迎您不喜欢它,但说使用“this”存在问题是一种误导。这是一个可接受的“this”用例。
  • $scope 没有增加清晰度。事实上,在使用 $scope 并且您有嵌套范围时,很难知道视图中发生了什么。控制器作为语法以及使用它增加了更多的清晰度。在视图中,方法或属性源自哪个控制器的范围非常清晰。
  • 我同意@ddelrio1986。只是在使用 var vm = $scope 时遇到了引导选项卡和 agular 的问题。选项卡有自己的范围,因此您无法按预期使用 this,但使用 var vm = this,一切都会按预期工作。
【解决方案2】:

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

$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/

【讨论】:

  • 就我个人而言,我也遵循您使用 vm 的方法。我发现的唯一代码异味是当您需要专门与 $scope 交互时,例如订阅或广播事件,访问控制器内部的表单验证变量等。这会导致环境有些混合,即使您将控制器用作功能,您仍然需要注入 $scope。
  • 对。 $scope 在这种情况下仍然用于,但它更多地用作服务。当我们注入 Angular 服务($scope、$q 等)时,它们会提供我们需要的一些功能。 $scope 允许我们观察、应用、使用消息以及数据绑定。即使使用控制器作为,$scope 仍然使用,它只是抽象的
  • var vm = this; 是否也需要在视图中将其称为“vm”? '作为虚拟机的控制器'。它们必须相同吗?
  • @JohnPapa - SideWaffle 模板为什么不“返回 vm;”当使用控制器时?
  • @Kevin Controllers 有效地充当了一个 Ctor,因此已经返回“this”。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

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

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

      此外,它将确保您始终拥有至少一个 .在您的绑定表达式中,这会迫使您遵循don't bind to primitives 建议。

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

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

          Angular 文档明确告诉您建议使用this。除了 $scope 被删除这一事实之外,这足以让我不再使用 $scope

          【讨论】:

            【解决方案8】:

            我更喜欢组合。

            $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;
            

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-10-20
              • 1970-01-01
              • 2014-09-12
              • 2018-09-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多