Câu trả lời:
@
cho phép một giá trị được xác định trên thuộc tính chỉ thị được chuyển đến phạm vi cách ly của lệnh. Giá trị có thể là một giá trị chuỗi đơn giản ( myattr="hello"
) hoặc nó có thể là một chuỗi nội suy AngularJS với các biểu thức nhúng ( myattr="my_{{helloText}}"
). Hãy nghĩ về nó như giao tiếp "một chiều" từ phạm vi cha mẹ vào chỉ thị con. John Lindquist có một loạt các screencasts ngắn giải thích từng điều này. Screencast trên @ có tại đây: https://egghead.io/lessons/angularjs-isolate-scope-attribution-binding
&
cho phép phạm vi cô lập của lệnh để truyền các giá trị vào phạm vi cha để đánh giá trong biểu thức được xác định trong thuộc tính. Lưu ý rằng thuộc tính directive hoàn toàn là một biểu thức và không sử dụng cú pháp biểu thức dấu ngoặc kép. Điều này là khó khăn hơn để giải thích trong văn bản. Screencast trên & ở đây: https://egghead.io/lessons/angularjs-isolate-scope-expression-binding
=
thiết lập biểu thức ràng buộc hai chiều giữa phạm vi cách ly của lệnh và phạm vi cha. Những thay đổi trong phạm vi con được truyền đến cha mẹ và ngược lại. Hãy nghĩ về = như một sự kết hợp của @ và &. Screencast trên = ở đây: https://egghead.io/lessons/angularjs-isolate-scope-two-way-binding
Và cuối cùng ở đây là một screencast cho thấy cả ba được sử dụng cùng nhau trong một chế độ xem: https://egghead.io/lessons/angularjs-isolate-scope-review
Tôi muốn giải thích các khái niệm từ quan điểm kế thừa nguyên mẫu JavaScript. Hy vọng giúp đỡ để hiểu.
Có ba tùy chọn để xác định phạm vi của một lệnh:
scope: false
: Mặc định góc. Phạm vi của lệnh này chính xác là một trong phạm vi cha của nó ( parentScope
).scope: true
: Angular tạo ra một phạm vi cho chỉ thị này. Phạm vi nguyên mẫu kế thừa từ parentScope
.scope: {...}
: phạm vi bị cô lập được giải thích dưới đây. Chỉ scope: {...}
định xác định một isolatedScope
. An isolatedScope
không kế thừa tài sản từ parentScope
, mặc dù isolatedScope.$parent === parentScope
. Nó được định nghĩa thông qua:
app.directive("myDirective", function() {
return {
scope: {
... // defining scope means that 'no inheritance from parent'.
},
}
})
isolatedScope
không có quyền truy cập trực tiếp vào parentScope
. Nhưng đôi khi chỉ thị cần giao tiếp với parentScope
. Họ liên lạc qua @
, =
và &
. Chủ đề về việc sử dụng các biểu tượng @
, =
và &
đang nói về các kịch bản sử dụngisolatedScope
.
Nó thường được sử dụng cho một số thành phần phổ biến được chia sẻ bởi các trang khác nhau, như Modals. Phạm vi tách biệt ngăn ngừa ô nhiễm phạm vi toàn cầu và dễ dàng chia sẻ giữa các trang.
Dưới đây là một chỉ thị cơ bản: http://jsfiddle.net/7t984sf9/5/ . Một hình ảnh để minh họa là:
@
: ràng buộc một chiều@
chỉ đơn giản là chuyển tài sản từ parentScope
đến isolatedScope
. Nó được gọi one-way binding
, có nghĩa là bạn không thể sửa đổi giá trị của các parentScope
thuộc tính. Nếu bạn quen thuộc với kế thừa JavaScript, bạn có thể hiểu hai tình huống này một cách dễ dàng:
Nếu thuộc tính ràng buộc là một kiểu nguyên thủy, như interpolatedProp
trong ví dụ: bạn có thể sửa đổi interpolatedProp
, nhưng parentProp1
sẽ không bị thay đổi. Tuy nhiên, nếu bạn thay đổi giá trị của parentProp1
, interpolatedProp
sẽ bị ghi đè bằng giá trị mới (khi $ digest góc).
Nếu thuộc tính ràng buộc là một đối tượng, như parentObj
: vì thuộc tính được truyền vào isolatedScope
là tham chiếu, việc sửa đổi giá trị sẽ gây ra lỗi này:
TypeError: Cannot assign to read only property 'x' of {"x":1,"y":2}
=
: ràng buộc hai chiều=
được gọi two-way binding
, có nghĩa là bất kỳ sửa đổi nào childScope
cũng sẽ cập nhật giá trị trong parentScope
và ngược lại. Quy tắc này hoạt động cho cả nguyên thủy và đối tượng. Nếu bạn thay đổi loại ràng buộc parentObj
thành =
, bạn sẽ thấy rằng bạn có thể sửa đổi giá trị của parentObj.x
. Một ví dụ điển hình là ngModel
.
&
: ràng buộc chức năng&
cho phép lệnh gọi một số parentScope
hàm và truyền vào một số giá trị từ lệnh. Ví dụ: kiểm tra JSFiddle: & trong phạm vi chỉ thị .
Xác định một mẫu có thể nhấp trong chỉ thị như:
<div ng-click="vm.onCheck({valueFromDirective: vm.value + ' is from the directive'})">
Và sử dụng chỉ thị như:
<div my-checkbox value="vm.myValue" on-check="vm.myFunction(valueFromDirective)"></div>
Biến valueFromDirective
được truyền từ chỉ thị đến bộ điều khiển cha thông qua {valueFromDirective: ...
.
Tham khảo: Hiểu phạm vi
Không phải fiddle của tôi, nhưng http://jsfiddle.net/maxisam/QrCXh/ cho thấy sự khác biệt. Mấu chốt là:
scope:{
/* NOTE: Normally I would set my attributes and bindings
to be the same name but I wanted to delineate between
parent and isolated scope. */
isolatedAttributeFoo:'@attributeFoo',
isolatedBindingFoo:'=bindingFoo',
isolatedExpressionFoo:'&'
}
@ : ràng buộc một chiều
= : ràng buộc hai chiều
& : ràng buộc chức năng
AngularJS - Phạm vi biệt lập - @ vs = vs &
Các ví dụ ngắn với lời giải thích có sẵn tại liên kết dưới đây:
http://www.codeforeach.com/angularjs/angularjs-isreach-scopes-vs-vs
@ - ràng buộc một chiều
Trong chỉ thị:
scope : { nameValue : "@name" }
Theo quan điểm:
<my-widget name="{{nameFromParentScope}}"></my-widget>
= - ràng buộc hai chiều
Trong chỉ thị:
scope : { nameValue : "=name" },
link : function(scope) {
scope.name = "Changing the value here will get reflected in parent scope value";
}
Theo quan điểm:
<my-widget name="{{nameFromParentScope}}"></my-widget>
& - Chức năng gọi
Trong chỉ thị:
scope : { nameChange : "&" }
link : function(scope) {
scope.nameChange({newName:"NameFromIsolaltedScope"});
}
Theo quan điểm:
<my-widget nameChange="onNameChange(newName)"></my-widget>
Tôi đã mất một thời gian dài để thực sự xử lý việc này. Chìa khóa đối với tôi là hiểu rằng "@" là dành cho những thứ bạn muốn đánh giá tại chỗ và được truyền vào chỉ thị dưới dạng hằng số trong đó "=" thực sự vượt qua chính đối tượng.
Có một bài đăng blog hay giải thích điều này tại: http://blog.ramkes.io/technical/AngularJS-the-difference-b between -@-&-and-=-when-declaring-directives-USE-isolate-scopes