AngularJS: คำสั่งแยกขอบเขต - ตัวแปรขอบเขตไม่ได้กำหนด

ได้โปรดใครช่วยอธิบายฉันหน่อยได้ไหมว่าเหตุใดตัวแปรขอบเขตของ attrDir จึงมองเห็นได้ แต่ oneWay ไม่สามารถมองเห็นได้ ฉันคิดว่า scope: {} ก็โดดเดี่ยวเช่นกัน

angular.module('test', []);

angular.module('test').directive('attrDir', attrDir);

function attrDir(){
    return {

        scope: true,

        link: function(scope){
          scope.hello = 'attrDir';
        }

    };
}

angular.module('test').directive('oneWay', oneWay);

function oneWay(){
    return {

        scope: {
          data: '<?'
        },

        link: function(scope){
          scope.hello = 'oneWay';  
        }

    };
}

hello จะแสดงผลใน attr-dir เท่านั้น

<attr-dir>
  <span>{{hello}}</span>
</attr-dir>
<one-way>
  <span>{{hello}}</span>
</one-way>

นี่คือเสียงระเบิด: https://plnkr.co/edit/2CM4vVRshWuJvaBj2q8T?p=preview

ขอบคุณ.


person Kindzoku    schedule 10.03.2017    source แหล่งที่มา
comment
ควรสังเกตว่าไม่มีคำตอบใดที่ตอบคำถามได้อย่างถูกต้อง   -  person Estus Flask    schedule 11.03.2017
comment
เอสตุสพูดถูก - one way !== isolated scopes   -  person lin    schedule 11.03.2017
comment
@lin ดูคำตอบที่ถูกต้อง ที่นี่   -  person Max Koretskyi    schedule 11.03.2017
comment
ตอนนี้พลังอยู่กับคินซึโกะ   -  person lin    schedule 11.03.2017


คำตอบ (4)


ประการแรก สิ่งที่คุณสังเกตไม่เกี่ยวข้องกับการผูก <

ปัญหาคือนิพจน์ {{hello}} ภายในทั้งสองคำสั่ง ไม่ได้ เป็นส่วนหนึ่งของเทมเพลตของคำสั่งเหล่านี้ และสำหรับองค์ประกอบดังกล่าว กฎสำหรับการผูกจะแตกต่างกัน

เชิงมุมจะสร้างฟังก์ชันลิงก์สำหรับนิพจน์ {{hello}} โดยอัตโนมัติ แต่ขอบเขตที่ฟังก์ชันลิงก์เหล่านี้ได้รับการประเมินจะแตกต่างกันในกรณีของคุณ

สิ่งที่คุณคาดหวังคือ:

            rootScope
         /             \
        /               \
attr-dir-new-scope  one-way-isoloate-scope
      /                   \
     /                     \
{{hello}}               {{hello}}

อย่างไรก็ตาม ตามความคิดเห็นนี้ในแหล่งที่มา:

// เราจะผ่านขอบเขตการแยกเท่านั้น หากคำสั่งแยกมีเทมเพลต
// มิฉะนั้น องค์ประกอบลูกจะไม่อยู่ในคำสั่งแยก

ภาพจริงคือ:

             root scope
         /             \    \
        /               \    \
attr-dir-new-scope       \    one-way-isoloate-scope
      /                   \
     /                     \
{{hello}}               {{hello}}

ดังนั้นในตัวอย่างของคุณ คำสั่งแรก <attr-dir> ไม่ได้สร้างขอบเขตแบบแยก แต่จะสร้างขอบเขตใหม่ ดังนั้นเมื่อการเชื่อมโยงเชิงมุมส่งผ่านขอบเขตใหม่นี้ไปยังฟังก์ชันการเชื่อมโยงของคำสั่งของคุณ:

link: function(scope){
     scope.hello = 'attrDir';
}

และฟังก์ชันการเชื่อมโยงที่สร้างขึ้นสำหรับนิพจน์ {{hello}} นั่นเป็นสาเหตุที่เมื่อคุณเพิ่มค่าในฟังก์ชันการเชื่อมโยง ค่านั้นจะพร้อมใช้งานในฟังก์ชันการเชื่อมโยงนิพจน์

แต่คำสั่งที่สองของคุณ <one-way> จะสร้าง ขอบเขตที่แยกออก และตามความคิดเห็นที่ฉันกล่าวถึงข้างต้น ฟังก์ชันการเชื่อมโยงของคำสั่งจะได้รับ ขอบเขตที่แยกออก ตามที่ควร แต่ฟังก์ชันการเชื่อมโยงของ นิพจน์ได้รับ ขอบเขตที่แตกต่างกัน (ขอบเขตหลักในตัวอย่างของคุณ) คุณกำลังเพิ่มค่า hello ในขอบเขตที่ต่างกัน นั่นเป็นเหตุผลว่าทำไมค่าจึงไม่ได้ถูกกำหนดไว้

person Max Koretskyi    schedule 11.03.2017
comment
คุณช่วยแสดงให้เราเห็นว่าคำสั่ง <one-way ที่สันนิษฐานของคุณใช้ ขอบเขตแยก โดยใช้ <? ได้อย่างไร - person Gangadhar JANNU; 11.03.2017
comment
@GangadharJannu, >? ไม่ได้ใช้ขอบเขตแบบแยก ขอบเขตแบบแยกถูกนำไปใช้โดยการระบุวัตถุสำหรับคุณสมบัติ scope ในวัตถุคำจำกัดความคำสั่ง - person Max Koretskyi; 11.03.2017
comment
หากเป็นเช่นนั้น <? หมายถึงอะไร - person Gangadhar JANNU; 11.03.2017
comment
BTW ที่ไม่ใช่ >? OP พยายาม <? ในคำสั่งของเขา - person Gangadhar JANNU; 11.03.2017
comment
@Maximum ฉันรู้ว่า ? หมายถึงอะไร เราไม่สามารถสรุปได้ว่ามีอะไรอยู่ในแหล่งกำเนิดเชิงมุม แต่เรากำลังตอบสิ่งที่ OP ถาม เป็นปัญหาคือ data: '<?' - person Gangadhar JANNU; 11.03.2017
comment
@GangadharJannu ฉันใช้ >? ในความคิดเห็นของฉันโดยไม่ได้ตั้งใจ ไม่มีความผูกพันดังกล่าว - person Max Koretskyi; 11.03.2017
comment
ฉันรู้ว่าไม่มีอะไรที่เหมือนกับ >? - person Gangadhar JANNU; 11.03.2017

ทั้งสองขอบเขต: จริงและขอบเขต:{} จะสร้างขอบเขตย่อยสำหรับคำสั่ง แต่,

scope:true จะสืบทอดคุณสมบัติต้นแบบจากพาเรนต์ (เช่น ตัวควบคุมที่มีคำสั่งอยู่ภายใต้) โดยที่ asscope:{} จะไม่สืบทอดคุณสมบัติจากพาเรนต์และด้วยเหตุนี้จึงเรียกว่าแยก

เนื่องจาก oneWay เป็นคำสั่งขอบเขตที่แยกออกมา และคุณไม่ได้ผ่านสวัสดี ดังนั้นจึงไม่ได้กำหนดไว้ใน HTML

person Pankaj Kumar Singh    schedule 11.03.2017

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

วิธีที่ดีที่สุดในการแสดงภาพขอบเขตคือการใช้คำสั่ง console.log ในฟังก์ชันลิงก์ของคุณดังนี้

link: function(scope) {          
      scope.hello = 'attrDir';
      console.log('scope in attrDir: ', scope);
    }

    link: function(scope) {          
          scope.hello = 'oneWay';
          console.log('scope in oneWay: ', scope);
        }

หากคุณเปิดเครื่องมือสำหรับนักพัฒนา คุณจะเห็นว่าคำสั่งแรกสืบทอดขอบเขตหลักในต้นแบบ

__proto__:Scope 

ในขณะที่อันที่สองเป็นวัตถุที่มีขอบเขตของตัวเอง (โดยใช้วงเล็บปีกกาคุณให้ขอบเขตแยก)

__proto__:Object
person Latin Warrior    schedule 11.03.2017

เนื่องจากคุณกำลังใช้การผูกส่วนประกอบในคำสั่ง

สัญลักษณ์ ‹ แสดงถึงการเชื่อมโยงทางเดียวซึ่งมีให้ใช้งานตั้งแต่เวอร์ชัน 1.5

หากคุณต้องการแสดงองค์ประกอบ hello ใน one-way คุณควรเปลี่ยนการใช้งานดังนี้:

HTML

 <one-way hello="$ctrl.hello">
      <span>{{$ctrl.hello}}</span>
    </one-way>

JS

angular.module('test').component('oneWay', {
  bindings:{
    hello:'='
  },
  controller: function() {
    this.hello = 'oneWay';
  }
});

การสาธิต

plnkr

person Gangadhar JANNU    schedule 11.03.2017
comment
คุณกำลังบอกว่า directive การใช้ < กลายเป็นส่วนประกอบภายใต้ประทุนใช่ไหม - person Kindzoku; 11.03.2017
comment
@คินด์โซกุ. ฉันกำลังบอกว่าไม่มีอะไรที่เหมือนกับ < การผูกมัดในคำสั่ง หากคุณต้องการใช้คุณต้องใช้ใน component ซึ่งเปิดตัวในเชิงมุม 1.5 - person Gangadhar JANNU; 11.03.2017
comment
สิ่งนี้ตอบคำถามได้อย่างไร? แม้ว่าจะไม่มีการเชื่อมโยง data: '<?' แต่ก็จะยังคงเหมือนเดิม - person Estus Flask; 11.03.2017
comment
@estus. OP พยายามใช้ < ซึ่งไม่แสดงในการเชื่อมโยงคำสั่ง ดังนั้นฉันจึงแนะนำให้เขาใช้ส่วนประกอบหากเขาต้องการใช้การผูก < - person Gangadhar JANNU; 11.03.2017
comment
@GangadharJannu คำตอบของคุณผิด ดูคำตอบที่ถูกต้องที่นี่ - person Max Koretskyi; 11.03.2017
comment
@Kindzoku โปรดดูคำตอบที่ถูกต้องที่นี่ - person Max Koretskyi; 11.03.2017
comment
@Maximus คุณอาจอธิบายแนวคิดนี้ในบริบทอื่นแล้ว เพียงเพราะคุณอธิบายในลักษณะที่แตกต่างกันไม่ได้หมายความว่าคำตอบอื่นผิด OP ถาม เหตุใดตัวแปรขอบเขตของ attrDir จึงมองเห็นได้ และ oneWay ไม่เป็นเช่นนั้น และฉันอธิบายในบริบทของการผูกส่วนประกอบเชิงมุม 1.5 เนื่องจาก OP ใช้ < ในคำสั่งซึ่งไม่ได้มีอยู่ทั้งหมด ฉันจึงแนะนำให้เขาใช้ < - person Gangadhar JANNU; 11.03.2017
comment
@all ก่อนที่จะลงคะแนน เพียงพูดถึงบริบทของคุณเพื่อที่ฉันจะพิจารณามัน - person Gangadhar JANNU; 11.03.2017
comment
@GangadharJannu, angular 1.5 component bindings ใช้กับ เทมเพลตคำสั่ง และไม่มีคำสั่งในกรณี OP ที่ใช้เทมเพลต นอกจากนี้ สัญลักษณ์ < ยังใช้สำหรับคำสั่งเช่นกัน เนื่องจากส่วนประกอบเป็นคำสั่งภายใต้ประทุน และประการที่สาม OP ใช้เวอร์ชัน 1.5 ในตัวอย่างของเขา - person Max Koretskyi; 11.03.2017
comment
หากเป็นสาเหตุ คุณช่วยแสดงให้ฉันเห็นว่าเราจะนำ < ไปใช้งานในคำสั่งได้อย่างไร เพราะฉันไม่แน่ใจจริงๆ เกี่ยวกับเรื่องนั้น - person Gangadhar JANNU; 11.03.2017
comment
@GangadharJannu ตรวจสอบ พลั่วนี้เพื่อดู < ที่ใช้ในคำสั่ง นอกจากนี้ คุณยังดูที่นี่ ส่วนประกอบนั้นเป็นเพียงคำสั่งที่หรูหรา - person Max Koretskyi; 11.03.2017