Tôi nên sử dụng `this` hay` $ scope`?


251

Có hai mẫu được sử dụng để truy cập các chức năng của bộ điều khiển: this$scope.

Nên dùng loại nào và khi nào? Tôi hiểu thisđược đặt thành bộ điều khiển và $scopelà một đối tượng trong chuỗi phạm vi cho các khung nhìn. Nhưng với cú pháp "Bộ điều khiển dưới dạng Var" mới, bạn có thể dễ dàng sử dụng. Vì vậy, những gì tôi đang hỏi là những gì là tốt nhất và định hướng cho tương lai là gì?

Thí dụ:

  1. Sử dụng this

    function UserCtrl() {
      this.bye = function() { alert('....'); };
    }
    <body ng-controller='UserCtrl as uCtrl'>
      <button ng-click='uCtrl.bye()'>bye</button>
  2. Sử dụng $scope

    function UserCtrl($scope) {
        $scope.bye = function () { alert('....'); };
    }
    <body ng-controller='UserCtrl'>
        <button ng-click='bye()'>bye</button>

Cá nhân tôi thấy this.namedễ nhìn hơn và tự nhiên hơn so với các mẫu OO Javascript khác.

Xin tư vấn?


Sử dụng 'this' dường như là mới kể từ Google I / O 2013 m.youtube.com/watch?v=HCR7i5F5L8c Ngoài ra, hãy kiểm tra câu trả lời này: stackoverflow.com/questions/11605917/,
AlanW

Cú pháp "UserCtrl as uCtrl" có mới không? Tôi không thấy nó được ghi lại trên các trang ngControll 1.0.6 hoặc 1.1.4.
Mark Rajcok

Được rồi, nó được ghi lại trên trang 1.1.5 ngControll mới .
Mark Rajcok

1
Giải thích tốt nhất cho phạm vi $ và codetunnel.io/angularjs-controll-as-or-scope
Sai

Câu trả lời:


229

Cả hai đều có công dụng của chúng. Đầu tiên, một số lịch sử ...

$ scope là kỹ thuật "cổ điển" trong khi "bộ điều khiển như" gần đây hơn nhiều (kể từ phiên bản 1.2.0 chính thức mặc dù nó đã xuất hiện trong các bản phát hành trước không ổn định trước đó).

Cả hai đều hoạt động hoàn hảo và câu trả lời sai duy nhất là trộn chúng trong cùng một ứng dụng mà không có lý do rõ ràng. Thành thật mà nói, trộn chúng sẽ làm việc, nhưng nó sẽ chỉ thêm vào sự nhầm lẫn. Vì vậy, chọn một và cuộn với nó. Điều quan trọng nhất là phải nhất quán.

Cái nào? Điều đó phụ thuộc vào bạn. Có rất nhiều ví dụ khác về phạm vi $, nhưng "bộ điều khiển như" cũng đang lấy hơi. Cái này tốt hơn những cái khác phải không? Điều đó có thể tranh luận. Vậy bạn chọn như thế nào?

Thoải mái

Tôi thích "trình điều khiển là" vì tôi thích ẩn phạm vi $ và hiển thị các thành viên từ bộ điều khiển sang chế độ xem thông qua một đối tượng trung gian. Bằng cách đặt này. *, Tôi có thể hiển thị chính những gì tôi muốn hiển thị từ bộ điều khiển sang chế độ xem. Bạn cũng có thể làm điều đó với $ scope, tôi chỉ thích sử dụng JavaScript tiêu chuẩn cho việc này. Trong thực tế, tôi mã nó như thế này:

var vm = this;

vm.title = 'some title';
vm.saveData = function(){ ... } ;

return vm;

Điều này cảm thấy sạch hơn đối với tôi và giúp dễ dàng nhìn thấy những gì đang được tiếp xúc với chế độ xem. Lưu ý tôi đặt tên cho biến mà tôi trả về "vm", viết tắt của viewmodel. Đó chỉ là quy ước của tôi.

Với $ scope tôi có thể làm những điều tương tự, vì vậy tôi không thêm hoặc làm giảm kỹ thuật.

$scope.title = 'some title';
$scope.saveData = function() { ... };

Vì vậy, nó phụ thuộc vào bạn ở đó.

Mũi tiêm

Với $ scope tôi cần phải tiêm $ scope vào bộ điều khiển. Tôi không phải làm điều này với bộ điều khiển, trừ khi tôi cần nó vì một số lý do khác (như $ Broadcast hoặc đồng hồ, mặc dù tôi cố gắng tránh đồng hồ trong bộ điều khiển).

CẬP NHẬT Tôi đã viết bài đăng này về 2 sự lựa chọn: http://www.johnpapa.net/do-you-like-your-angular-controllers-with-or-without-sugar/


4
Cá nhân tôi cũng làm theo cách tiếp cận của bạn bằng cách sử dụng vm. Mùi mã duy nhất tôi đã chọn là khi bạn cần tương tác cụ thể với $ scope, ví dụ: đăng ký hoặc phát sóng các sự kiện, truy cập các biến xác thực mẫu trong bộ điều khiển của bạn, v.v. Điều này dẫn đến một môi trường hơi hỗn hợp khi bạn vẫn cần tiêm $ scope mặc dù bạn sử dụng bộ điều khiển như tính năng.
Beyers 17/11/13

9
Đúng. $ scope vẫn được sử dụng trong trường hợp đó, nhưng nó được sử dụng nhiều hơn như một dịch vụ. Khi chúng tôi cung cấp các dịch vụ góc ($ scope, $ q, v.v.), chúng sẽ cung cấp một số tính năng chúng tôi cần. $ scope cho phép chúng ta xem, áp dụng, sử dụng tin nhắn cũng như ràng buộc dữ liệu. Và ngay cả khi sử dụng bộ điều khiển như, phạm vi $ vẫn được sử dụng, nó chỉ được trừu tượng hóa
John Papa

1
var vm = this;bạn có cần gọi nó là 'vm' trong chế độ xem không? 'điều khiển như vm'. Họ có phải giống nhau không?
Javid

2
@JohnPapa - Tại sao các mẫu SideWaff không "return vm;" Khi sử dụng Bộ điều khiển Như?
Kevin

2
@Kevin Bộ điều khiển hoạt động hiệu quả như một Ctor và do đó trả lại "cái này".
John Papa

68

$scopeđang được gỡ bỏ trong Angular 2.0. Do đó, sử dụng thissẽ là một cách tiếp cận mà người khác muốn theo dõi khi ngày phát hành Angular 2.0 đến gần hơn.


40

Ý kiến ​​của tôi là 'cái này' trong javascript có đủ vấn đề của riêng nó và việc thêm một ý nghĩa / sử dụng khác cho nó không phải là một ý tưởng hay.

Tôi sẽ sử dụng $ scope, vì mục đích rõ ràng.

CẬP NHẬT

Bây giờ có cú pháp 'bộ điều khiển như', được thảo luận ở đây . Tôi không phải là một người hâm mộ, nhưng bây giờ nó là một AngularJS 'chính thức' hơn, nó đáng được chú ý.


10
Tôi nghĩ rằng trước tiên chúng ta cần hiểu cú pháp "UserCtrl as uCtrl" mới trước khi chúng ta có thể nói rằng chúng ta nghĩ là tốt hơn.
Mark Rajcok

Re 'UserCtrl là uCtrl', tôi đồng ý, điều này cần được hiểu. Tôi nghĩ rằng đó là một ý tưởng tồi, vì hầu hết các lý do tương tự như các đối số được đưa ra ở đây: Groups.google.com/forum/#!topic/angular/84selECbp1I
Roy Truelove

4
Nếu bạn quen thuộc với oop trong JS, nó có ý nghĩa hoàn hảo. Bộ điều khiển là một lớp và góc sử dụng toán tử mới mỗi khi bộ điều khiển được tạo. Bạn có thể không thích nó, nhưng nói rằng có vấn đề với việc sử dụng 'cái này' là sai lệch. Đây là trường hợp sử dụng được chấp nhận cho 'cái này'.
MJ

$ scope không thêm gì vào sự rõ ràng. Trong thực tế, có thể rất khó để biết những gì đang diễn ra trong chế độ xem khi sử dụng $ scope và bạn có phạm vi lồng nhau. Bộ điều khiển như cú pháp cùng với việc sử dụng này thêm rõ ràng hơn nhiều. Theo quan điểm, thật hay và rõ ràng phạm vi của bộ điều khiển mà một phương thức hoặc thuộc tính bắt nguồn từ đâu.
ddelrio1986

1
Tôi đồng ý với @ ddelrio1986. Chỉ có một vấn đề với các tab bootstrap và agular với việc sử dụng var vm = $ scope. Các tab có phạm vi riêng và vì vậy bạn không thể sử dụng điều này như bạn mong đợi nhưng với var vm = this, mọi thứ chỉ hoạt động như mong đợi.
dùng441521

11

Tôi nghĩ Bộ điều khiển As tốt hơn vì nó cho phép phạm vi lồng dễ dàng hơn như được mô tả bởi Phương châm của Todd ở đây:

http://toddmotto.com/digging-into-angenses-controll-as-syntax/

Ngoài ra, nó sẽ đảm bảo rằng bạn luôn có ít nhất một. trong biểu thức ràng buộc của bạn mà buộc bạn phải tuân theo đừng liên kết với giới thiệu nguyên thủy .

Ngoài ra, bạn có thể tách rời khỏi phạm vi sẽ biến mất trong 2.0.


7

Tài liệu Angular rõ ràng cho bạn biết rằng nên sử dụng this. Điều đó, ngoài việc thực tế $scopelà bị loại bỏ là đủ lý do để tôi không bao giờ sử dụng $scope.


4

"Phạm vi $ đang bị xóa trong Angular 2.0" của jason328 nghe có vẻ là một lý do chính đáng với tôi. Và tôi tìm thấy một lý do khác để giúp tôi đưa ra lựa chọn: thisnhiều hơn dễ đọc - khi tôi thấy fooCtrl.bartrong HTML, tôi biết ngay nơi tìm định nghĩa bar.

Cập nhật: không lâu sau khi chuyển sang thisgiải pháp, tôi bắt đầu nhớ $scopecách cần gõ ít hơn


2

Tôi thích một sự kết hợp.

Một console.log đơn giản có phạm vi $ và 'cái này' sau khi điền chúng với một số dữ liệu giả sẽ cho bạn thấy điều đó.

$ scope cho phép truy cập vào bên dưới các bộ phận của bộ điều khiển, ví dụ:

$$ChildScope: null;
$$childHead: null;
$$childTail: null;
$$listenerCount: Object;
$$listeners: Object;
$$nextSibling: Scope;
$$prevSibling: null;
$$watchers: null;
$$watcherCount: 0;
$id: 2;
$parent: Object;
foo: 'bar';

** Các thuộc tính và phương thức với $$ không được nhóm Angular khuyên dùng, nhưng $ có thể là trò chơi an toàn để làm những thứ hay ho với $ Parent và $ id.

'cái này' đi thẳng vào vấn đề, gắn các dữ liệu và chức năng ràng buộc 2 chiều. Bạn sẽ chỉ thấy những gì bạn đính kèm:

foo: 'bar';

Vậy tại sao tôi thích kết hợp?

Trong các ứng dụng lồng nhau của bộ định tuyến, tôi có thể truy cập bộ điều khiển chính, đặt và gọi các giá trị và hàm phổ quát bên trong bộ điều khiển con:

Trong Bộ điều khiển chính:

// Main Controller
var mainCtrl = this;
mainCtrl.foo = 'Parent at the bar';

Trong Bộ điều khiển trẻ em:

// Child Controller
var mainCtrl = $scope.$parent.mainCtrl;
var childCtrl = this;

// update the parent from within the child
childCtrl.underageDrinking = function(){
    mainCtrl.foo = 'Child at the bar';
}

// And then attach the child back to a property on the parent controller!
mainCtrl.currentCtrl = childCtrl;

Bây giờ, bạn có thể truy cập cha mẹ từ bên trong trẻ em và trẻ em từ cha mẹ!


1

Cả hai đều hoạt động, nhưng nếu bạn áp dụng những thứ phù hợp với phạm vi cho $ scope và nếu bạn áp dụng những thứ phù hợp với bộ điều khiển cho bộ điều khiển, mã của bạn sẽ dễ dàng duy trì. Đối với những người nói rằng "Ugh chỉ sử dụng phạm vi hãy quên Bộ điều khiển này làm cú pháp" ... Nó có thể hoạt động tương tự nhưng tôi tự hỏi làm thế nào bạn có thể duy trì một ứng dụng khổng lồ mà không mất dấu vết.

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.