AngularJS – Sử dụng cú pháp Controller as và $scope

angularjs-logoGiới thiệu về cú pháp Controller as trong AngularJS, qua đó bạn có thể quyết định xem nên sử dụng cách trong hai sự lựa chọn này.

Giới thiệu

Hiện tại, Controller as là cú pháp mới được nhiều người khuyến khích sử dụng hơn so với $scope. Với cú pháp này, một instance của controller sẽ được tạo và gán vào $scope dựa theo tên mà bạn đặt. Ví dụ bạn sử dụng controller với cú pháp InvoiceController as invoice, angularjs sẽ tự động tạo ra một thuộc tính invoice trên $scope. Hãy xem hình minh họa sau:

concepts-databinding2(nguồn ảnh: angularjs.org)

Với phiên bản Angularjs từ 1.3, bạn có thể kiểm tra như sau:

app.controller('TestController', function($scope) {
this.isTheSame = $scope.test === this; // true
});

Cách sử dụng

Hãy so sánh hai phương pháp này với nhau để thấy sự khác biệt, với cách sử dụng $scope:

app.controller('TestController', function ($scope) {
$scope.someValue = 'Hello dude!';
});
<div ng-controller="TestController"> 
 {{ someValue }}
</div>

Với cú pháp Controller as, bạn có thể viết như sau:

app.controller('TestController', function () {
this.someValue = 'Hello dude!';
});
<div ng-controller="TestController as test"> 
 {{ test.someValue }}
</div> 

Với $scope, bạn có thể gặp phải những rắc rối từ việc kế thừa $scope khi sử dụng các controller lồng nhau. Việc thừa kế $scope có thể là một ưu điểm trong một vài trường hợp, nhưng nó khiến bạn phải chú ý và cẩn thận và ghi nhớ từng thuộc tính, từng controller để tránh xảy ra các sai sót. Thường là dự đoán sai các giá trị của thuộc tính. Và với Controller as, bạn sẽ thấy nó cung cấp một cách viết rõ ràng và an toàn hơn khi sử dụng:

<div ng-controller="FatherController as father"> 
 Father's name: {{ father.name }}
 <div ng-controller="SonController as son">
 {{ son.name }} is a son of {{ father.name }}
 </div>
</div> 

$watch

Trong thực tế, bởi vì từ khóa this sẽ có giá trị khác nhau trong từng ngữ cảnh, nên để tiện, người ta thường gán this vào một biến vm (viết tắt của ViewModel) để sử dụng. Ví dụ như khi cần xài $watch, bạn có thể làm như sau:

app.controller('TestController', function($scope) {
var vm = this;
vm.name = 'Bill';

$scope.$watch(function(){
return vm.name;
}, function (newVal, oldVal) {
if(newVal)
{
$scope.message = 'length: ' + newVal.length;
}
});
});

hoặc như sau, nếu bạn biết chắc instance của controller được đặt là ‘login’:

$scope.$watch('login.name', function (newVal, oldVal) {
// ...
});

OK, cuối cùng là phần để bạn quyết định xem sẽ chọn lựa cách viết nào cho các project của mình.

YinYangIt Blog