【问题标题】:Angular's "controllerAs" not working in routeProviderAngular 的“controllerAs”在 routeProvider 中不起作用
【发布时间】:2014-10-08 00:26:16
【问题描述】:

我正在尝试在 $routeProvider 路由上使用 controllerAs 属性,但没有成功。

这里是示例代码:

var app = angular.module('app', ['ngRoute']);

app.config(['$routeProvider', '$locationProvider',
  function($routeProvider) {
  $routeProvider
    .when('/', {
      template:'<div>This should be visible:{{ ctrl.one }}</div><div>This should not:{{ one }}</div>',
      controller: 'Ctrl',
      controllerAs: 'ctrl',
    });
}]);

app.controller('Ctrl', function($scope) {
  $scope.one = 'actual';
});

不确定这是错误还是我做错了什么,This is a plnkr that demonstrates the issue

【问题讨论】:

    标签: angularjs angularjs-routing


    【解决方案1】:

    如果您使用$scope,则必须在函数末尾添加return $scopecontrollerAs 语法才能起作用。

    app.controller('Ctrl', function($scope) {
        $scope.one = 'actual';
    
        // return $scope
        return $scope;
    });
    

    祝你好运。

    【讨论】:

      【解决方案2】:

      实际问题:

      您最初似乎在使用controllerAs(分配'ctrl' 的值),但后来没有在其余代码中使用它。 (你用了$scope

      解决方案:

      Working demo as per your sample

      当我一直使用 controllerAs 语法时,您需要使用以下模式之一来访问控制器实例:

      与将属性附加到$scope 不同,您必须绑定到控制器范围。请注意,这与$scope 不同。由于缺少更好的术语,您需要绑定控制器本身(将其视为其上下文)。当我们处理显示层或视图模型时,我倾向于使用var vm = this; 作为惯例,但这是个人偏好。

      [A]:首选解决方案

      app.controller('Ctrl', function() {        
          this.one = 'actual';  
      });
      
      //or using 'vm' convention
      
      app.controller('Ctrl', function() {
          var vm = this;
          vm.one = 'actual';  
      });
      

      [B]

      app.controller('Ctrl', function() {
          var vm = {};
          vm.one = 'actual';
          return vm;
      });
      

      说明:

      当我第一次开始使用 Angular 时,[B] 是我使用的方法,纯粹来自 Knockout 背景。我习惯于绑定到“容器”对象,然后将对象绑定到视图。话虽如此,我更喜欢使用 [A],或者直接附加到 $scope 并完全放弃别名。原因:

      • 我觉得它更清晰的 ITO 可读性
      • 正如@Swordfish0321 所说,[A] 性能更高(您是否应该担心)
      • 我编写的自定义指令存在绑定问题,这些指令依赖于某些父范围属性(特定于我的代码库)

      只是视觉效果:

      Demo

       app.controller('Ctrl', function($scope) {
            var vm = this;
            vm.one = 'actual'; 
            console.log($scope) 
       });
      

      传入$scope 对象并进一步检查它,您将看到一个新的ctrl 子对象,其中包含绑定到控制器代码中vm 的所有公共属性和函数。这是因为您分配了var vm = this。这意味着代码中的vm 对象正在引用控制器自己的范围,最终将绑定到视图。 controllerAs 基本上将控制器内部包含的所有属性和函数分组到一个以您提供的别名命名的新对象中。

      【讨论】:

      • 为什么我需要更改如何创作控制器的模式?当在标记中内联使用“as”时,情况并非如此:ng-controller="Ctrl as ctrl" 这是怎么回事?
      • 当你使用 inline ng-controller="myController as vm" 时,你仍然需要和我上面的两个例子一样。我们不在我们的一个项目中使用 ui-router,同样适用。我个人还没有深入了解原因(我自己还是很新奇)。我的假设是控制器为视图创建 $scope,并通过使用 controllerAs 来限制视图绑定/可以访问的内容。例如,您返回的 vm/ctrl 对象将嵌套在原始 $scope 内...如果这有意义的话。我将发布一个小的更新来说明我的意思。
      【解决方案3】:

      要清楚——因为我不认为接受的答案是明确的——你的例子的问题是,即使你为controllerAs 赋值,你也在绕过它仍然使用$scope

      “vm”方法代表 view-model,这只是一种约定,但 IMO 比“$scope”更能代表实际发生的情况。我们在这里真正要做的就是将视图绑定到视图模型。

      话虽如此,您可以同时使用 controllerAs 和普通 $scope plunk

      此外,Rohan 的示例 A 和 B 之间的区别在于 A 是您应该这样做的方式,因为您能够利用 JavaScript 的原型继承,这有助于提高性能。还值得注意的是,由于您现在使用的是 controllerAsthis,因此您不再需要注入 $scope。

      // Functioning Example    
      var app = angular.module('app', ['ngRoute']);
      
      app.config(['$routeProvider', '$locationProvider',
        function($routeProvider) {
        $routeProvider
          .when('/', {
            template:'<div>This should be visible:{{ vm.one }}</div><div>This should not:{{ one }}</div>',
            controller: 'Ctrl',
            controllerAs: 'vm',
          });
      }]);
      
      app.controller('Ctrl', function() {
        this.one = 'actual';
      });
      

      【讨论】:

      • 感谢您澄清和改写我的回答。 TBH 当我最初回答时...更多时间和后见之明的力量)。我也喜欢认为自己是 JavaScript 的所有事物的持续学习者,我肯定也从你的回答中学到了一些东西,ITO 以某种方式措辞解决方案......话虽如此,但它真的值得投反对票吗?
      • 嘿,罗汉,np。我自己尝试以持续的方式学习。您最初的答案非常冗长,实际上并没有回答 OP 的真正问题——这就是投反对票的原因。但是,由于您正在维护答案以改进它,因此我不赞成它。希望这是有道理的!
      【解决方案4】:

      controllerAs是控制器实例的别名,如果你想使用它,你必须将数据存储到控制器实例this而不是$scope

      app.controller('Ctrl', function($scope) {
        var ctrl = this; // assign to a variable to be consistent when using in the template
        ctrl.one = 'actual';
      });
      

      Plunker 示例: http://plnkr.co/edit/r8AYtSKbiLQAaPBPriRp?p=preview

      【讨论】:

        猜你喜欢
        • 2016-07-14
        • 2015-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-03
        • 2015-09-05
        相关资源
        最近更新 更多