อะไรคือความแตกต่างระหว่าง & vs @ และ = ใน angularJS


238

ฉันยังใหม่กับ AngularJS มาก ใครสามารถอธิบายความแตกต่างให้ฉันได้ระหว่างผู้ประกอบการ AngularJS เหล่านี้: &, @ and =เมื่อแยกขอบเขตด้วยตัวอย่างที่เหมาะสม


คำตอบ:


375

@อนุญาตให้ค่าที่กำหนดไว้ในแอตทริบิวต์ directive ถูกส่งผ่านไปยังขอบเขต isolate ของ directive ค่าอาจเป็นค่าสตริงแบบธรรมดา ( myattr="hello") หรืออาจเป็นสตริงที่สอดแทรก AngularJS ด้วยนิพจน์ที่ฝัง ( myattr="my_{{helloText}}") คิดว่าเป็นการสื่อสารแบบ "ทางเดียว" จากขอบเขตพาเรนต์ไปยังคำสั่งย่อย John Lindquist มีชุด screencasts สั้นอธิบายแต่ละเหล่านี้ Screencast บน @ อยู่ที่นี่: https://egghead.io/lessons/angularjs-isolate-scope-attribute-binding

&อนุญาตให้ขอบเขตแยกของ directive ส่งค่าไปยังขอบเขตพาเรนต์สำหรับการประเมินผลในนิพจน์ที่กำหนดในแอตทริบิวต์ โปรดทราบว่าแอตทริบิวต์คำสั่งเป็นการแสดงออกโดยนัยและไม่ใช้ไวยากรณ์การแสดงออกรั้งคู่หยิก อันนี้ยากที่จะอธิบายในข้อความ Screencast บน & อยู่ที่นี่: https://egghead.io/lessons/angularjs-isolate-scope-expression-binding

=ตั้งค่านิพจน์การโยงแบบสองทางระหว่างขอบเขต isolate ของ directive และขอบเขต parent การเปลี่ยนแปลงในขอบเขตลูกจะแพร่กระจายไปยังผู้ปกครองและในทางกลับกัน คิดว่า = เป็นการรวมกันของ @ และ & Screencast on = อยู่ที่นี่: https://egghead.io/lessons/angularjs-isolate-scope-two-way-binding

และสุดท้ายนี่คือ screencast ที่แสดงทั้งสามรายการที่ใช้ร่วมกันในมุมมองเดียว: https://egghead.io/lessons/angularjs-isolate-scope-review


3
ลิงก์ไปยังสิ่งเหล่านี้ดูเหมือนว่ามีการเปลี่ยนแปลงตอนนี้: egghead.io/lessons/angularjs-isolate-scope-attribute-binding , egghead.io/lessons/angularjs-isolate-scope-expression-binding , egghead.io/lessons / angularjs-isolate-scope-two-way-binding , egghead.io/lessons/angularjs-isolate-scope-reviewตามลำดับ
Samih

1
ขอบคุณสำหรับคำบรรยายภาพฉันอัปเดตคำตอบด้วย URL ที่ถูกต้อง
cliff.meyers

43
เป็นเรื่องน่าละอายที่คำตอบยอดนิยมเชื่อมโยงไปยังวิดีโอหลังกำแพงจ่ายเมื่ออาจมีการโหลดเนื้อหาฟรีที่มีข้อมูลเดียวกัน
BenCr

มีจำนวนมากของวิดีโอที่มีให้ฟรีโดยปัญญาชน :) มี
Vatsal

7
ลบหนึ่งรายการสำหรับเนื้อหาที่ต้องชำระเงิน
Arel Sapir

109

ฉันต้องการอธิบายแนวคิดจากมุมมองของการสืบทอดต้นแบบ JavaScript หวังว่าจะช่วยให้เข้าใจ

มีสามตัวเลือกในการกำหนดขอบเขตของคำสั่ง:

  1. scope: false: ค่าเริ่มต้นเชิงมุม ขอบเขตของไดเรกทีฟนั้นเป็นหนึ่งในขอบเขตพาเรนต์ ( parentScope)
  2. scope: true: เชิงมุมสร้างขอบเขตสำหรับคำสั่งนี้ สืบทอดขอบเขต prototypically parentScopeจาก
  3. scope: {...}: ขอบเขตที่แยกได้อธิบายไว้ด้านล่าง

ระบุกำหนดscope: {...} ไม่คุณสมบัติไม่ได้รับมรดกจากแม้ว่า มันถูกกำหนดผ่าน:isolatedScopeisolatedScopeparentScopeisolatedScope.$parent === parentScope

app.directive("myDirective", function() {
    return {
        scope: {
            ... // defining scope means that 'no inheritance from parent'.
        },
    }
})

isolatedScopeparentScopeไม่ได้มีการเข้าถึงโดยตรง parentScopeแต่บางครั้งคำสั่งจะต้องมีการสื่อสารกับ พวกเขาสื่อสารผ่าน@, และ= หัวข้อเกี่ยวกับการใช้สัญลักษณ์, และมีการพูดคุยเกี่ยวกับสถานการณ์การใช้&@=&isolatedScope

มันมักจะใช้สำหรับองค์ประกอบทั่วไปบางอย่างที่ใช้ร่วมกันโดยหน้าเว็บที่แตกต่างกันเช่น Modals ขอบเขตที่แยกได้ช่วยป้องกันมลพิษทั่วโลกและง่ายต่อการแชร์ระหว่างหน้าต่างๆ

นี่คือคำสั่งพื้นฐานhttp://jsfiddle.net/7t984sf9/5/ ภาพที่แสดงเป็น:

ป้อนคำอธิบายรูปภาพที่นี่

@: การรวมทางเดียว

@เพียงแค่ผ่านคุณสมบัติจากไปparentScope isolatedScopeมันถูกเรียกone-way bindingซึ่งหมายความว่าคุณไม่สามารถแก้ไขค่าของparentScopeคุณสมบัติ หากคุณคุ้นเคยกับการสืบทอด JavaScript คุณสามารถเข้าใจสถานการณ์ทั้งสองนี้ได้อย่างง่ายดาย:

  • หากคุณสมบัติการโยงเป็นชนิดดั้งเดิมเช่นinterpolatedPropในตัวอย่าง: คุณสามารถแก้ไขinterpolatedPropได้ แต่parentProp1จะไม่เปลี่ยนแปลง แต่ถ้าคุณเปลี่ยนค่าของparentProp1, interpolatedPropจะถูกเขียนทับด้วยค่าใหม่ (เมื่อเชิงมุม $ ย่อย)

  • หากคุณสมบัติการรวมเป็นวัตถุบางอย่างเช่นparentObj: เนื่องจากสิ่งที่ผ่านไปisolatedScopeเป็นการอ้างอิงการแก้ไขค่าจะทำให้เกิดข้อผิดพลาดนี้:

    TypeError: Cannot assign to read only property 'x' of {"x":1,"y":2}

=: การผูกสองทาง

=เรียกว่าtwo-way bindingซึ่งหมายถึงการแก้ไขใด ๆ ในchildScopeจะอัปเดตค่าในparentScopeและในทางกลับกัน กฎนี้ใช้ได้กับทั้งวัตถุพื้นฐานและวัตถุ ถ้าคุณเปลี่ยนชนิดผูกพันparentObjที่จะคุณจะพบว่าคุณสามารถปรับเปลี่ยนค่าของ= เป็นตัวอย่างparentObj.xngModel

&ฟังก์ชั่นที่มีผลผูกพัน

&อนุญาตให้คำสั่งเรียกparentScopeใช้ฟังก์ชันและส่งผ่านค่าบางค่าจากคำสั่ง ยกตัวอย่างเช่นการตรวจสอบJSFiddle: & สั่งอยู่ในขอบเขต

กำหนดเทมเพลตที่คลิกได้ในคำสั่ง like:

<div ng-click="vm.onCheck({valueFromDirective: vm.value + ' is from the directive'})">

และใช้คำสั่งเช่น:

<div my-checkbox value="vm.myValue" on-check="vm.myFunction(valueFromDirective)"></div>

ตัวแปรได้พ้นไปจากคำสั่งไปยังตัวควบคุมผู้ปกครองผ่านvalueFromDirective{valueFromDirective: ...

การอ้างอิง: การทำความเข้าใจขอบเขต


โดยค่าเริ่มต้นคำสั่งใช้ขอบเขตที่ใช้ร่วมกัน หากคำสั่งมี 'scope: true' ก็จะใช้ขอบเขตที่สืบทอดมาซึ่งลูกสามารถดูคุณสมบัติพาเรนต์ แต่พาเรนต์ไม่สามารถดูคุณสมบัติภายในของลูกได้
YuMei

1
AngularJS - แยกขอบเขต - @ VS = VS & ---------- ตัวอย่างที่มีคำอธิบายสั้นมีที่ลิงค์ด้านล่าง: codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs
Prashanth

24

ไม่ใช่ซอของฉัน แต่http://jsfiddle.net/maxisam/QrCXh/แสดงความแตกต่าง ชิ้นส่วนที่สำคัญคือ:

           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:'&'
        }        

17

@ : การเชื่อมโยงทางเดียว

= : การผูกสองทาง

& : ฟังก์ชันมีผลผูกพัน


5
ข้อแม้สำคัญสำหรับ @ ไม่ได้เป็นเพียงทางเดียว แต่เป็นสายระหว่างทาง
Shawson

@Shawson: ดังนั้นวิธีการผูกไม่ใช่ทางเดียว (เช่น int หรือบูล)?
หรือผู้ทำแผนที่

หากหัวใจของคุณตั้งอยู่บนมันคุณสามารถนำค่าจาก @ และ cast ไปเป็น int / bool หรือไม่? มิฉะนั้นฉันจะใช้ = หรือ <
Shawson

7

AngularJS - ขอบเขตที่แยกได้ - @ vs = vs &


ตัวอย่างสั้น ๆ พร้อมคำอธิบายมีอยู่ที่ลิงค์ด้านล่าง:

http://www.codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs

@ - การเชื่อมโยงทางเดียว

ในคำสั่ง:

scope : { nameValue : "@name" }

ในมุมมอง:

<my-widget name="{{nameFromParentScope}}"></my-widget>

= - การผูกสองทาง

ในคำสั่ง:

scope : { nameValue : "=name" },
link : function(scope) {
  scope.name = "Changing the value here will get reflected in parent scope value";
}

ในมุมมอง:

<my-widget name="{{nameFromParentScope}}"></my-widget>

& - ฟังก์ชั่นการโทร

ในคำสั่ง:

scope : { nameChange : "&" }
link : function(scope) {
  scope.nameChange({newName:"NameFromIsolaltedScope"});
}

ในมุมมอง:

<my-widget nameChange="onNameChange(newName)"></my-widget>

5

ฉันใช้เวลานานมากในการจัดการเรื่องนี้ กุญแจสำคัญสำหรับฉันคือในการทำความเข้าใจว่า "@" สำหรับสิ่งที่คุณต้องการประเมินในแหล่งกำเนิดและส่งผ่านเข้าไปในคำสั่งเป็นค่าคงที่โดยที่ "=" ผ่านวัตถุจริง

มีโพสต์บล็อกที่ดีที่อธิบายสิ่งนี้ได้ที่: http://blog.ramses.io/technical/AngularJS-the-difference-between-@-&-and-=-when-declaring-directives-using-isolate-scopes

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.