Angular“controllerAs”在routeProvider中不起作用

时间:2014-08-14 11:09:18

标签: angularjs angularjs-routing

我试图在controllerAs路线上使用$routeProvider属性,但没有成功。

以下是示例代码:

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

4 个答案:

答案 0 :(得分:15)

实际问题:

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

enter image description here

<强>解决方案:

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背景。我习惯于绑定一个&#34;容器&#34;然后将对象绑定到视图。话虽这么说,我更喜欢使用 [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基本上将控制器内部包含的所有属性和函数分组到以您提供的别名命名的新对象。

enter image description here

答案 1 :(得分:3)

要明确 - 因为我认为接受的答案不是明确 - 您的示例的问题是,即使您要为controllerAs分配值,仍然使用$scope绕过它。

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

如果说,您可以在技术上同时使用controllerAs和普通$ scope plunk

此外,Rohan的示例A和B之间的区别在于A是你应该这样做的方式,因为你能够利用JavaScript的原型继承,这有利于更好的性能。值得注意的是,因为您现在正在使用 controllerAs ,所以您不再需要注入$ 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';
});

答案 2 :(得分:2)

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

答案 3 :(得分:1)

如果您使用$scope,则必须在函数末尾return $scope才能使controllerAs语法正常运行。

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

    // return $scope
    return $scope;
});

祝你好运。