2015年2月3日 星期二

AngularJS-是否要使用ControllerAs以及vm變數

在學習Angular過程中,官方的教學都是將$scope注入controller中來控制及儲存資料.
但最近在看coding style時,有看到2個高手提到儘量使用"ControllerAs",而不要使用$scope.



他們有說明為何要這樣使用的原因:
1. 避免在巢狀的controller的應用下去使用到$parent的值. (可以看這篇及其中的範例http://stackoverflow.com/questions/11605917/this-vs-scope-in-angularjs-controllers)

<div ng-controller="ParentCtrl">
   <a ng-click="logThisAndScope()">log "this" and $scope</a> - parent scope
   <div ng-controller="ChildCtrl">
      <a ng-click="logThisAndScope()">log "this" and $scope</a> - child scope
   </div>
</div>

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

function ParentCtrl($scope) {
    $scope.logThisAndScope = function() {
        console.log(this, $scope)
    }
}
function ChildCtrl($scope) {}

在這個範例中,ChildCtrl會繼承parent controller(因為它被包在ng-controller="ParentCtrl"的div中).
當點擊parent csope的那個連結時,this和$scope是相等的.
當點擊child csope的那個連結時,this和$scope是不相等的, this指向的是ChildCtrl, 而$scope是指向ParentCtrl.

2. 只有在使用$emit, $broadcast, $on, $watch時,才去注入$scope

3. 若controller是作為綁定view的資料來源, 在設計controller時,用vm指向this,代表ViewModel.
// avoid
function MainCtrl () {
  var doSomething = function () {

  };
  this.doSomething = doSomething;
}

// recommended
function MainCtrl () {
  var vm = this;
  var doSomething = function () {

  };
  vm.doSomething = doSomething;
}

4. 在View的html中, John Papa建議使用Controller As, 並且建立"vm"變數來操作由ViewModel Controller取得的資料.
Case#1
<div ng-controller="Shell as vm">
<h1>{{vm.title}}</h1>
</div>

而在巢狀的應用下,可以用以下的程式碼規則
<div ng-controller="Shell as shellVm">
  <h1>{{shellVm.title}}</h1>
  <article ng-controller="Customers as customersVm">
    <h2>{{customersVm.title}} in {{shellVm.title}}</h2>
    <ul ng-repeat="c in customersVm.customers">
      <li>{{c.name}}</li>
    </ul>
  </article>
</div>


-------------

Toddmotto的AngularJS styleguide: https://github.com/toddmotto/angularjs-styleguide

John Papa的AngularJS’s Controller As and the vm Variable文章: http://www.johnpapa.net/angularjss-controller-as-and-the-vm-variable/



沒有留言:

張貼留言