Cú pháp AngularJs "controller as" - làm rõ?


121

Tôi đã đọc về cú pháp mới từ angleJS liên quan đếncontroller as xxx

Cú pháp InvoiceController as invoiceyêu cầu Angular khởi tạo bộ điều khiển và lưu nó trong hóa đơn biến đổi trong phạm vi hiện tại.

Hình dung :

nhập mô tả hình ảnh ở đây

Ok, vì vậy tôi sẽ không có tham số $scopetrong bộ điều khiển của mình và mã sẽ sạch hơn nhiều trong bộ điều khiển.

Nhưng

Tôi sẽ phải chỉ định một bí danh khác trong chế độ xem

Vì vậy, cho đến bây giờ tôi có thể làm:

<input type="number" ng-model="qty"  />

....controller('InvoiceController', function($scope) {
   // do something with $scope.qty <--notice

Và bây giờ tôi có thể làm:

 <input type="number" ng-model="invoic.qty"  /> <-- notice 

  ....controller('InvoiceController', function() {
       // do something with  this.qty  <--notice

Câu hỏi

Mục tiêu của việc làm đó là gì? xóa khỏi một nơi và thêm vào một nơi khác?

Tôi sẽ rất vui khi thấy những gì tôi còn thiếu.


8
Video này giải thích nó rất tốt. youtube.com/watch?v=tTihyXaz4Bo tôi nghĩ nó được sử dụng cho mã rõ ràng hơn trong HTML.
Fizer Khan

1
Trong trẻo. Tôi không thấy phiền về việc sử dụng $ scope.x Vs this.x trong bộ điều khiển, nhưng theo quan điểm của tôi, ràng buộc với {{bill.x}} cho tôi biết nhiều điều hơn là chỉ {{x}} (imho). Ngoài ra, tôi đang tự hỏi liệu điều này có giải quyết một vấn đề mà tôi đã nghe nói đến trong góc mà các đối tượng không phải trong bộ điều khiển có vấn đề hay không (vì vậy, things.x sẽ ổn, nhưng x sẽ gây ra sự cố).
Matt Roberts

1
@MattRoberts để giải quyết nhận xét cuối cùng của bạn - vấn đề không phải đối tượng mà bạn tham khảo không phải là một vấn đề góc cạnh giống như một thực tế về kế thừa nguyên mẫu javascript. Có một lời giải thích tốt về lý do tại sao nó xảy ra trong góc ở đây (cùng với lý do tại sao controller assửa nó).
Russ Matney

Tôi sẽ thay thế $ scope. $ Broadcast như thế nào? . trong trường hợp mới này vì đây $ phát sóng của tôi không dường như được làm việc
Gaurav

1
@Gaurav, bạn vẫn có thể đưa dịch vụ $ scope vào bộ điều khiển của mình, ngay cả khi bạn sử dụng bộ điều khiển làm cú pháp cho một số thuộc tính, phương thức, v.v.
Derek

Câu trả lời:


163

Có một số điều về nó.

Một số người không thích $scopecú pháp (đừng hỏi tôi tại sao). Họ nói rằng họ chỉ có thể sử dụng this. Đó là một trong những mục tiêu.

Việc làm rõ tài sản đến từ đâu cũng thực sự hữu ích.

Bạn có thể lồng các bộ điều khiển và khi đọc html, bạn có thể thấy khá rõ ràng mọi thuộc tính ở đâu.

Bạn cũng có thể tránh một số vấn đề về quy tắc chấm .

Ví dụ: có hai bộ điều khiển, cả hai đều có cùng tên 'name', Bạn có thể thực hiện điều này:

<body ng-controller="ParentCtrl">
    <input ng-model="name" /> {{name}}

    <div ng-controller="ChildCtrl">
        <input ng-model="name" /> {{name}} - {{$parent.name}}
    </div>
</body>

Bạn có thể sửa đổi cả cha và con, không có vấn đề gì về điều đó. Nhưng bạn cần sử dụng $parentđể xem tên của cha mẹ, vì bạn đã ẩn tên đó trong bộ điều khiển con của bạn. Trong mã html lớn $parentcó thể có vấn đề, bạn không biết tên đó đến từ đâu.

Với controller asbạn có thể làm:

<body ng-controller="ParentCtrl as parent">
    <input ng-model="parent.name" /> {{parent.name}}

    <div ng-controller="ChildCtrl as child">
      <input ng-model="child.name" /> {{child.name}} - {{parent.name}}
    </div>
</body>

Cùng một ví dụ, nhưng nó rõ ràng hơn nhiều để đọc.


10
Ngoài ra đây là một ví dụ khá tốt về việc tại sao phương pháp này có thể gây nhầm lẫn đối với một số: stackoverflow.com/questions/25405543/...
Julian Hollmann

Điều này rất hữu ích khi bạn lồng bộ điều khiển!
C_J

1
Tôi đang gặp sự cố với cách triển khai tương tự cho câu trả lời của bạn, vui lòng xem stackoverflow.com/questions/38315538
Cody

Điều này cũng cho phép bạn sử dụng lớp es6 làm bộ điều khiển và tham chiếu các phương thức trong HTML. foo() { ... }là cách sạch hơn $scope.foo = function() { ... }.
Brian McCutchon

17

Ưu điểm chính với controller ascú pháp mà tôi thấy là bạn có thể làm việc với bộ điều khiển như các lớp, không chỉ một số hàm $ scope-decor và tận dụng tính kế thừa. Tôi thường gặp phải tình huống khi có một chức năng rất giống với một số bộ điều khiển và điều rõ ràng nhất cần làm là tạo một BaseControllerlớp và kế thừa từ nó.

Mặc dù có kế thừa $ scope, giải quyết một phần vấn đề này, nhưng một số người thích viết mã theo cách OOP hơn, theo tôi, điều này làm cho mã dễ lập luận và kiểm tra hơn.

Đây là một trò đùa để chứng minh: http://jsfiddle.net/HB7LU/5796/


1
Điều này sẽ nhận được nhiều ủng hộ hơn, vì Fiddle thực sự hữu ích
Mawg nói hãy phục hồi Monica

13

Tôi tin rằng một lợi thế cụ thể là rõ ràng khi bạn có các phạm vi lồng nhau. Bây giờ sẽ hoàn toàn rõ ràng chính xác phạm vi mà một tham chiếu thuộc tính đến từ.


7

Nguồn

Sự khác biệt giữa Tạo bộ điều khiển bằng cách sử $scope objectdụng “controller as”cú pháp và vm

Tạo bộ điều khiển bằng đối tượng $ scope

Thông thường, chúng tôi tạo một bộ điều khiển bằng cách sử dụng đối tượng $ scope như được hiển thị trong danh sách bên dưới:

myApp.controller("AddController", function ($scope) {



    $scope.number1;

    $scope.number2;

    $scope.result;

    $scope.add = function () {

        $scope.result = $scope.number1 + $scope.number2;

    }

});

Ở trên, chúng ta đang tạo AddController với ba biến và một hành vi, sử dụng bộ điều khiển và chế độ xem đối tượng $ scope, chúng nói chuyện với nhau. Đối tượng $ scope được sử dụng để truyền dữ liệu và hành vi tới dạng xem. Nó gắn kết chế độ xem và bộ điều khiển với nhau.

Về cơ bản, đối tượng $ scope thực hiện các tác vụ sau:

  1. Truyền dữ liệu từ bộ điều khiển sang chế độ xem

  2. Chuyển hành vi từ bộ điều khiển sang chế độ xem

  3. Dán bộ điều khiển và xem với nhau

  4. Đối tượng $ scope được sửa đổi khi một dạng xem thay đổi và một dạng xem được sửa đổi khi các thuộc tính của đối tượng $ scope thay đổi

Chúng tôi đính kèm các thuộc tính vào một đối tượng $ scope để truyền dữ liệu và hành vi đến chế độ xem. Trước khi sử dụng đối tượng $ scope trong bộ điều khiển, chúng ta cần chuyển nó vào hàm bộ điều khiển dưới dạng phụ thuộc.

Sử dụng cú pháp "controller as" và vm

Chúng ta có thể viết lại bộ điều khiển ở trên bằng cách sử dụng bộ điều khiển dưới dạng cú pháp và biến vm như được hiển thị trong danh sách dưới đây:

myApp.controller("AddVMController", function () {

    var vm = this;

    vm.number1 = undefined;

    vm.number2=undefined;

    vm.result =undefined;

    vm.add = function () {

        vm.result = vm.number1 + vm.number2;

    }

});

Về cơ bản, chúng tôi đang gán điều này cho một biến vm và sau đó gắn một thuộc tính và hành vi vào đó. Trên khung nhìn, chúng ta có thể truy cập AddVmController bằng cú pháp controller. Điều này được hiển thị trong danh sách dưới đây:

<div ng-controller="AddVMController as vm">

            <input ng-model="vm.number1" type="number" />

            <input ng-model="vm.number2" type="number" />

            <button class="btn btn-default" ng-click="vm.add()">Add</button>

            <h3>{{vm.result}}</h3>

  </div>

Tất nhiên, chúng ta có thể sử dụng một tên khác không phải là “vm” trong bộ điều khiển làm cú pháp. Dưới mui xe, AngularJS tạo đối tượng $ scope và đính kèm các thuộc tính và hành vi. Tuy nhiên, bằng cách sử dụng bộ điều khiển làm cú pháp, mã rất rõ ràng ở bộ điều khiển và chỉ có tên bí danh được hiển thị trên khung nhìn.

Dưới đây là một số bước để sử dụng bộ điều khiển theo cú pháp:

  1. Tạo một bộ điều khiển mà không có đối tượng $ scope.

  2. Gán điều này cho một biến cục bộ. Tôi ưu tiên tên biến là vm, bạn có thể chọn bất kỳ tên nào tùy ý.

  3. Đính kèm dữ liệu và hành vi vào biến vm.

  4. Trên dạng xem, đặt bí danh cho bộ điều khiển bằng cách sử dụng bộ điều khiển làm cú pháp.

  5. Bạn có thể đặt bất kỳ tên nào cho bí danh. Tôi thích sử dụng vm trừ khi tôi không làm việc với bộ điều khiển lồng nhau.

Trong việc tạo bộ điều khiển, không có lợi thế hoặc bất lợi trực tiếp của việc sử dụng phương pháp tiếp cận đối tượng $ scope hoặc bộ điều khiển làm cú pháp. Tuy nhiên, việc sử dụng bộ điều khiển làm cú pháp sẽ làm cho mã JavaScript của bộ điều khiển dễ đọc hơn và ngăn chặn bất kỳ vấn đề nào liên quan đến ngữ cảnh này.

Bộ điều khiển lồng nhau trong phương pháp tiếp cận đối tượng $ scope

Chúng tôi có hai bộ điều khiển như được hiển thị trong danh sách dưới đây:

myApp.controller("ParentController", function ($scope) {



    $scope.name = "DJ";

    $scope.age = 32;

});

myApp.controller("ChildController", function ($scope) {



    $scope.age = 22;

    $scope.country = "India";



});

Thuộc tính “age” nằm bên trong cả hai bộ điều khiển và trên giao diện hai bộ điều khiển này có thể được lồng vào nhau như được hiển thị trong danh sách bên dưới:

<div ng-controller="ParentController">



            <h2>Name :{{name}} </h2>

            <h3>Age:{{age}}</h3>



             <div ng-controller="ChildController">

                    <h2>Parent Name :{{name}} </h2>

                    <h3>Parent Age:{{$parent.age}}</h3>

                    <h3>Child Age:{{age}}</h3>

                    <h3>Country:{{country}}</h3>

             </div>

        </div>

Như bạn thấy, để truy cập thuộc tính tuổi của bộ điều khiển mẹ, chúng ta đang sử dụng $ parent.age. Sự tách biệt ngữ cảnh không rõ ràng lắm ở đây. Nhưng sử dụng bộ điều khiển làm cú pháp, chúng ta có thể làm việc với các bộ điều khiển lồng nhau theo cách thanh lịch hơn. Giả sử chúng ta có bộ điều khiển như được hiển thị trong danh sách bên dưới:

myApp.controller("ParentVMController", function () {

    var vm = this;

    vm.name = "DJ";

    vm.age = 32;

});

myApp.controller("ChildVMController", function () {

    var vm = this;

    vm.age = 22;

    vm.country = "India";



});

Trên giao diện hai bộ điều khiển này có thể được lồng vào nhau như được hiển thị trong danh sách dưới đây:

<div ng-controller="ParentVMController as parent">



            <h2>Name :{{parent.name}} </h2>

            <h3>Age:{{parent.age}}</h3>



            <div ng-controller="ChildVMController as child">

                <h2>Parent Name :{{parent.name}} </h2>

                <h3>Parent Age:{{parent.age}}</h3>

                <h3>Child Age:{{child.age}}</h3>

                <h3>Country:{{child.country}}</h3>

            </div>

 </div>

Trong cú pháp bộ điều khiển, chúng ta có mã dễ đọc hơn và thuộc tính mẹ có thể được truy cập bằng cách sử dụng tên bí danh của bộ điều khiển mẹ thay vì sử dụng cú pháp $ cha.

Tôi sẽ kết thúc bài đăng này bằng cách nói rằng đó hoàn toàn là lựa chọn của bạn cho dù bạn muốn sử dụng bộ điều khiển làm cú pháp hay đối tượng $ scope. Không có lợi thế hay bất lợi lớn nào đối với cả hai, chỉ đơn giản là bộ điều khiển dưới dạng cú pháp mà bạn có quyền kiểm soát trên ngữ cảnh dễ làm việc hơn một chút, với sự phân tách rõ ràng trong các bộ điều khiển lồng nhau trên khung nhìn.


4

Tôi thấy ưu điểm chính là api trực quan hơn vì các phương thức / thuộc tính được liên kết trực tiếp với cá thể bộ điều khiển chứ không phải đối tượng phạm vi. Về cơ bản, với cách tiếp cận cũ, bộ điều khiển chỉ trở thành một vật trang trí để xây dựng đối tượng phạm vi.

Dưới đây là một số thông tin khác về điều này: http://www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff


3

Từ những gì tôi đã đọc, $ scope sẽ bị xóa trong Angular 2.0 hoặc ít nhất là cách chúng tôi xem việc sử dụng $ scope. Có thể tốt khi bắt đầu sử dụng bộ điều khiển khi bản phát hành 2.0 sắp ra mắt.

Liên kết video ở đây để thảo luận thêm về nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.