ความแตกต่างระหว่างรวบรวมและฟังก์ชั่นการเชื่อมโยงใน angularjs คืออะไร


208

ใครบางคนสามารถอธิบายได้ในแง่ง่าย ๆ ?

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


2
บางทีอาจจะเป็นภาพรวมที่ครอบคลุมมากขึ้นของฟังก์ชั่นสั่ง: สั่งเชิงมุม - เมื่อจะใช้รวบรวมควบคุมก่อนการเชื่อมโยงและการโพสต์ลิงค์
Izhaki

คำตอบ:


217
  • ฟังก์ชั่นการคอมไพล์ - ใช้สำหรับการจัดการ DOM แม่แบบ (เช่นการจัดการขององค์ประกอบ tElement = เท็มเพลต) ดังนั้นการจัดการที่ใช้กับ DOM clones ทั้งหมดของเทมเพลตที่เกี่ยวข้องกับคำสั่ง

  • ฟังก์ชั่นการเชื่อมโยง - ใช้สำหรับการลงทะเบียนผู้ฟัง DOM (เช่น $ watch expressions บนขอบเขตของอินสแตนซ์) รวมถึงการจัดการ DOM อินสแตนซ์ (เช่นการจัดการของ iElement = องค์ประกอบอินสแตนซ์แต่ละรายการ)
    มันจะดำเนินการหลังจากที่แม่แบบได้รับการโคลน ตัวอย่างเช่นภายใน <li ng-repeat ... > ฟังก์ชั่นการเชื่อมโยงจะดำเนินการหลังจากเทมเพลต <li> (tElement) ถูกโคลน (เป็น iElement) สำหรับองค์ประกอบ <li> นั้น
    $ watch () ช่วยให้คำสั่งได้รับแจ้งจากการเปลี่ยนแปลงคุณสมบัติขอบเขตอินสแตนซ์ (ขอบเขตอินสแตนซ์นั้นเชื่อมโยงกับแต่ละอินสแตนซ์) ซึ่งช่วยให้คำสั่งแสดงผลค่าอินสแตนซ์ที่อัปเดตไปยัง DOM DOM

โปรดทราบว่าการแปลง DOM สามารถทำได้ในฟังก์ชันคอมไพล์และ / หรือฟังก์ชันลิงก์

คำสั่งส่วนใหญ่ต้องการฟังก์ชันลิงก์เท่านั้นเนื่องจากคำสั่งส่วนใหญ่จะจัดการกับอินสแตนซ์องค์ประกอบ DOM เฉพาะเท่านั้น (และขอบเขตอินสแตนซ์ของมัน)

วิธีหนึ่งที่จะช่วยพิจารณาว่าจะใช้อย่างไร: ให้พิจารณาว่าฟังก์ชั่นการคอมไพล์ไม่ได้รับการ scopeโต้แย้ง (ฉันจงใจละเว้น transclude เชื่อมโยงอาร์กิวเมนต์ฟังก์ชั่นซึ่งได้รับขอบเขต transcluded - นี้ไม่ค่อยได้ใช้) ดังนั้นฟังก์ชั่นการคอมไพล์ไม่สามารถทำสิ่งที่คุณต้องการที่จะต้องมีขอบเขต (ตัวอย่าง) - คุณสามารถ ไม่ได้ดูคุณสมบัติขอบเขต / โมเดลของอินสแตนซ์ใด ๆ คุณไม่สามารถจัดการ DOM โดยใช้ข้อมูลขอบเขตอินสแตนซ์คุณไม่สามารถเรียกฟังก์ชันที่กำหนดไว้ในขอบเขตอินสแตนซ์ ฯลฯ

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

นี่คือตัวอย่างของคำสั่งที่ใช้ฟังก์ชันคอมไพล์เท่านั้น คำสั่งจำเป็นต้องแปลง DOM แม่แบบเท่านั้นดังนั้นจึงสามารถใช้ฟังก์ชันคอมไพล์ได้

อีกวิธีในการช่วยพิจารณาว่าจะใช้: หากคุณไม่ใช้พารามิเตอร์ "องค์ประกอบ" ในฟังก์ชันลิงก์คุณอาจไม่จำเป็นต้องใช้ฟังก์ชันลิงก์

เนื่องจากคำสั่งส่วนใหญ่มีฟังก์ชั่นลิงก์ฉันจะไม่ให้ตัวอย่างใด ๆ - มันควรจะหาได้ง่าย

โปรดทราบว่าถ้าคุณต้องการฟังก์ชั่นคอมไพล์และฟังก์ชั่นลิงค์ (หรือฟังก์ชั่นก่อนและโพสต์ลิงค์) ฟังก์ชั่นคอมไพล์จะต้องส่งกลับฟังก์ชั่นการเชื่อมโยงเพราะแอตทริบิวต์ 'ลิงค์' ถูกละเว้นหากมีการกำหนดแอตทริบิวต์

ดูสิ่งนี้ด้วย


5
คำอธิบายที่ดีที่สุดเกี่ยวกับการคอมไพล์ vs ลิงค์
Nexus23

1
เมื่อคุณพูดว่าif you don't use the "element" parameter in the link function, then you probably don't need a link function.คุณหมายถึง "scope" แทนที่จะเป็น "element"
Jason Larke

69

ฉันตีหัวของฉันกับกำแพงในสองสามวันนี้และฉันรู้สึกว่าคำอธิบายเพิ่มเติมเล็กน้อยอยู่ในลำดับ

โดยทั่วไปเอกสารระบุว่าการแยกส่วนใหญ่เป็นการปรับปรุงประสิทธิภาพ ฉันจะย้ำว่าขั้นตอนการคอมไพล์ส่วนใหญ่จะใช้เมื่อคุณต้องการแก้ไข DOM ก่อนองค์ประกอบย่อยจะรวบรวม

เพื่อจุดประสงค์ของเราฉันจะเน้นคำศัพท์ซึ่งอาจทำให้สับสน:

คอมไพเลอร์ SERVICE ($ compile) เป็นกลไกเชิงมุมที่ประมวลผล DOM และรันบิตของรหัสต่าง ๆ ในคำสั่ง

ฟังก์ชั่นการคอมไพล์เป็นโค้ดหนึ่งบิตภายในคำสั่งซึ่งจะรันในเวลาใดเวลาหนึ่งโดยคอมไพเลอร์ SERVICE ($ คอมไพล์)

หมายเหตุบางประการเกี่ยวกับฟังก์ชั่นการคอมไพล์:

  1. คุณไม่สามารถแก้ไของค์ประกอบ ROOT (สิ่งที่มีผลกับคำสั่งของคุณ) เนื่องจากมันถูกคอมไพล์แล้วจากระดับนอกของ DOM (คอมไพล์ SERVICE ได้สแกนแล้วสำหรับคำสั่งในองค์ประกอบนั้น)

  2. หากคุณต้องการเพิ่มคำสั่งอื่น ๆ ให้กับองค์ประกอบ (ซ้อนกัน) คุณจะ:

    1. ต้องเพิ่มพวกเขาในระหว่างขั้นตอนการรวบรวม

    2. ต้องฉีดบริการรวบรวมเข้าไปในขั้นตอนการเชื่อมโยงและรวบรวมองค์ประกอบด้วยตนเอง แต่ระวังการรวบรวมบางสิ่งบางอย่างสองครั้ง!

นอกจากนี้ยังเป็นประโยชน์ในการดูวิธีการทำรังและบริการโทรอย่างชัดเจนถึง $ ทำงานรวบรวมดังนั้นผมจึงได้สร้างสนามเด็กเล่นสำหรับการดูว่าในhttp://jsbin.com/imUPAMoV/1/edit โดยทั่วไปเพียงบันทึกขั้นตอนใน console.log

ฉันจะระบุผลลัพธ์ของสิ่งที่คุณเห็นในถังขยะที่นี่ สำหรับ DOM ของคำสั่งกำหนดเอง tp และ sp ซ้อนกันดังนี้:

<tp>
   <sp>
   </sp>
</tp>

SERVICE compile เชิงมุมจะโทรหา:

tp compile
sp compile
tp pre-link
sp pre-link
sp post-link
tp post-link

รหัส jsbin ยังมีฟังก์ชั่น tp post-link FUNCTION เรียกบริการรวบรวมอย่างชัดเจนในคำสั่งที่สาม (ขึ้นไป) ซึ่งทำทั้งสามขั้นตอนในตอนท้าย

ตอนนี้ฉันต้องการเดินผ่านสองสถานการณ์เพื่อแสดงให้เห็นว่าอาจมีการใช้คอมไพล์และลิงค์เพื่อทำสิ่งต่าง ๆ :

สถานการณ์ที่ 1: คำสั่งเป็นมาโคร

คุณต้องการเพิ่มคำสั่ง (พูด ng-show) แบบไดนามิกให้กับบางสิ่งในแม่แบบของคุณที่คุณสามารถรับมาจากแอตทริบิวต์

สมมติว่าคุณมี templateUrl ที่ชี้ไปที่:

<div><span><input type="text"></span><div>

และคุณต้องการคำสั่งที่กำหนดเอง:

<my-field model="state" name="address"></my-field>

ที่เปลี่ยน DOM เป็นสิ่งนี้:

<div><span ng-show="state.visible.address"><input ng-model="state.fields.address" ...>

โดยทั่วไปคุณต้องการลดสำเร็จรูปโดยมีโครงสร้างรูปแบบที่สอดคล้องกันซึ่งคำสั่งของคุณสามารถตีความ กล่าวอีกนัยหนึ่ง: คุณต้องการแมโคร

นี่เป็นการใช้งานที่ยอดเยี่ยมสำหรับขั้นตอนการคอมไพล์เนื่องจากคุณสามารถยึดหลัก DOM ทั้งหมดกับสิ่งที่คุณรู้จากแอตทริบิวต์ เพียงใช้ jQuery เพื่อเพิ่มคุณสมบัติ:

compile: function(tele, tattr) {
   var span = jQuery(tele).find('span').first();
   span.attr('ng-show', tattr.model + ".visible." + tattr.name);
   ...
   return { 
     pre: function() { },
     post: function() {}
   };
}

ลำดับของการดำเนินการจะเป็น (คุณสามารถดูได้ผ่านทาง jsbin ที่กล่าวถึงก่อนหน้านี้):

  1. SERVICE ที่คอมไพล์พบ my-field
  2. มันเรียกการรวบรวมฟังก์ชั่นในคำสั่งซึ่งการปรับปรุง DOM
  3. SERVICE คอมไพล์แล้วเดินเข้าไปใน DOM ผลลัพธ์และคอมไพล์ (เรียกซ้ำ)
  4. SERVICE ที่คอมไพล์แล้วเรียกลิงค์จากบนลงล่างล่วงหน้า
  5. SERVICE คอมไพล์แล้วเรียกใช้ post-link BOTTOM UP ดังนั้นฟังก์ชันลิงค์ของฟิลด์ของฉันถูกเรียกว่าโหนดตกแต่งภายในหลังจากที่มีการเชื่อมโยง

ในตัวอย่างข้างต้นไม่จำเป็นต้องมีการเชื่อมโยงเนื่องจากงานทั้งหมดของคำสั่งได้ทำในการรวบรวมฟังก์ชั่น

รหัสใด ๆ ในคำสั่งสามารถขอให้คอมไพเลอร์ SERVICE ทำงานบนองค์ประกอบเพิ่มเติม

ซึ่งหมายความว่าเราสามารถทำสิ่งเดียวกันในฟังก์ชั่นลิงค์ถ้าคุณฉีดบริการรวบรวม:

directive('d', function($compile) {
  return {
    // REMEMBER, link is called AFTER nested elements have been compiled and linked!
    link: function(scope, iele, iattr) {
      var span = jQuery(iele).find('span').first();
      span.attr('ng-show', iattr.model + ".visible." + iattr.name);
      // CAREFUL! If span had directives on it before
      // you will cause them to be processed again:
      $compile(span)(scope);
    }
});

หากคุณแน่ใจว่าองค์ประกอบที่คุณส่งไปยัง $ compile SERVICE นั้นไม่มีคำสั่งโดยตรง (เช่นมาจากเทมเพลตที่คุณกำหนดไว้หรือคุณเพิ่งสร้างมันด้วย angular.element ()) ผลลัพธ์ที่ได้นั้นค่อนข้างมาก เหมือนก่อนหน้า (แม้ว่าคุณอาจจะทำซ้ำบางงาน) อย่างไรก็ตามหากองค์ประกอบนั้นมีคำสั่งอื่น ๆ อยู่คุณเพียงแค่ทำให้สิ่งนั้นถูกประมวลผลอีกครั้งซึ่งอาจทำให้เกิดพฤติกรรมที่ไม่แน่นอน (เช่นการลงทะเบียนซ้ำสองครั้งของเหตุการณ์และนาฬิกา)

ดังนั้นขั้นตอนการคอมไพล์จึงเป็นทางเลือกที่ดีกว่ามากสำหรับงานสไตล์มาโคร

สถานการณ์ที่ 2: การกำหนดค่า DOM ผ่านข้อมูลขอบเขต

อันนี้ตามมาจากตัวอย่างข้างต้น สมมติว่าคุณต้องการเข้าถึงขอบเขตในขณะที่จัดการ DOM ในกรณีนั้นส่วนคอมไพล์นั้นไม่มีประโยชน์กับคุณเพราะมันเกิดขึ้นก่อนที่ขอบเขตจะพร้อมใช้งาน

ดังนั้นสมมติว่าคุณต้องการรวบรวมอินพุตด้วยการตรวจสอบความถูกต้อง แต่คุณต้องการส่งออกการตรวจสอบความถูกต้องของคุณจากเซิร์ฟเวอร์ ORM class (DRY) และให้พวกเขาใช้อัตโนมัติและสร้าง UI ฝั่งไคลเอ็นต์ที่เหมาะสมสำหรับการตรวจสอบเหล่านั้น

แบบจำลองของคุณอาจผลักดัน:

scope.metadata = {
  validations: {
     address: [ {
       pattern: '^[0-9]',
       message: "Address must begin with a number"
     },
     { maxlength: 100,
       message: "Address too long"
     } ]
  }
};
scope.state = {
  address: '123 Fern Dr'
};

และคุณอาจต้องการคำสั่ง:

<form name="theForm">
  <my-field model="state" metadata="metadata" name="address">
</form>

เพื่อรวมคำสั่งและ div ที่เหมาะสมโดยอัตโนมัติเพื่อแสดงข้อผิดพลาดในการตรวจสอบความถูกต้องต่างๆ:

<form name="theForm">
  <div>
    <input ng-model="state.address" type="text">
    <div ng-show="theForm.address.$error.pattern">Address must begin with a number</input>
...

ในกรณีนี้คุณต้องเข้าถึงขอบเขตอย่างแน่นอน (เนื่องจากเป็นที่เก็บการตรวจสอบความถูกต้องของคุณ) และจะต้องรวบรวมการเพิ่มด้วยตนเองอีกครั้งระวังอย่าให้คอมไพล์ซ้ำอีกครั้ง (เป็นบันทึกด้านข้างคุณจะต้องตั้งชื่อบนแท็กแบบฟอร์มที่มี (ฉันสมมติว่าแบบฟอร์มที่นี่) และสามารถเข้าถึงได้ในลิงก์ด้วย iElement.parent (). controller ('form'). $ name) .

ในกรณีนี้ไม่มีจุดในการเขียนฟังก์ชั่นการคอมไพล์ ลิงก์เป็นสิ่งที่คุณต้องการจริงๆ ขั้นตอนจะเป็น:

  1. กำหนดเทมเพลตที่ไม่มีคำสั่งเชิงมุมอย่างสมบูรณ์
  2. กำหนดฟังก์ชั่นลิงค์ที่เพิ่มคุณสมบัติต่าง ๆ
  3. ลบคำสั่งเชิงมุมใด ๆ ที่คุณอาจอนุญาตให้ใช้กับองค์ประกอบระดับบนสุดของคุณ (คำสั่งเขตข้อมูลของฉัน) พวกเขาได้รับการประมวลผลแล้วและนี่คือวิธีที่จะป้องกันพวกเขาจากการถูกประมวลผลซ้ำ
  4. เสร็จสิ้นโดยการเรียกใช้บริการรวบรวมในองค์ประกอบระดับบนสุดของคุณ

ชอบมาก

angular.module('app', []).
directive('my-field', function($compile) {
  return {
    link: function(scope, iele, iattr) {
      // jquery additions via attr()
      // remove ng attr from top-level iele (to avoid duplicate processing)
      $compile(iele)(scope); // will pick up additions
    }
  };
});

แน่นอนว่าคุณสามารถรวบรวมองค์ประกอบที่ซ้อนกันทีละตัวเพื่อหลีกเลี่ยงการกังวลเกี่ยวกับการประมวลผลคำสั่ง ng ที่ซ้ำกันเมื่อคุณรวบรวมองค์ประกอบระดับบนสุดอีกครั้ง

หนึ่งบันทึกสุดท้ายเกี่ยวกับสถานการณ์นี้: ฉันบอกเป็นนัยว่าคุณกำลังผลักดันคำจำกัดความของการตรวจสอบความถูกต้องจากเซิร์ฟเวอร์และในตัวอย่างของฉันฉันได้แสดงให้พวกเขาเป็นข้อมูลที่อยู่ในขอบเขตแล้ว ฉันปล่อยให้มันเป็นแบบฝึกหัดสำหรับผู้อ่านที่จะหาวิธีจัดการกับความต้องการดึงข้อมูลนั้นจาก REST API (คำแนะนำ: การคอมไพล์ที่รอการตัดบัญชี)

สถานการณ์ที่ 3: การผูกข้อมูลแบบสองทางผ่านลิงก์

แน่นอนว่าการใช้ลิงก์ที่ใช้กันมากที่สุดก็คือการเชื่อมโยงข้อมูลสองทางเข้าด้วยกันผ่าน watch / Apply คำสั่งส่วนใหญ่ตกอยู่ในหมวดหมู่นี้จึงครอบคลุมอย่างเพียงพอที่อื่น


2
คำตอบที่น่ากลัวและยอดเยี่ยม!
Nexus23

วิธีการเพิ่มองค์ประกอบซ้อนกันโดยไม่ต้องรวบรวมคู่?
Art713

50

จากเอกสาร:

ผู้รวบรวม

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

  1. คอมไพล์:สำรวจ DOM และรวบรวมคำสั่งทั้งหมด ผลที่ได้คือฟังก์ชั่นการเชื่อมโยง

  2. ลิงก์:รวมคำสั่งเข้ากับขอบเขตและสร้างมุมมองแบบสด การเปลี่ยนแปลงใด ๆ ในโมเดลขอบเขตจะสะท้อนให้เห็นในมุมมองและการโต้ตอบของผู้ใช้กับมุมมองจะแสดงในโมเดลขอบเขต การทำให้แบบจำลองขอบเขตเป็นแหล่งความจริงเดียว

คำสั่งบางอย่างเช่นng-repeatองค์ประกอบ DOM โคลนหนึ่งครั้งสำหรับแต่ละรายการในคอลเลกชัน การมีคอมไพล์และเฟสลิงก์จะปรับปรุงประสิทธิภาพเนื่องจากเทมเพลตโคลนจะต้องรวบรวมเพียงครั้งเดียวแล้วเชื่อมโยงหนึ่งครั้งสำหรับแต่ละอินสแตนซ์การโคลน

อย่างน้อยในบางกรณีทั้งสองเฟสจึงแยกกันเป็นการเพิ่มประสิทธิภาพ


จาก @ UmurKontacı :

หากคุณกำลังจะทำให้การเปลี่ยนแปลง DOM compileมันควรจะเป็น linkหากคุณต้องการที่จะเพิ่มคุณสมบัติบางอย่างที่มีการเปลี่ยนแปลงพฤติกรรมก็ควรจะอยู่ใน


46
หากคุณกำลังจะทำให้DOMการเปลี่ยนแปลงมันควรจะเป็นถ้าคุณต้องการที่จะเพิ่มคุณสมบัติบางอย่างมีการเปลี่ยนแปลงพฤติกรรมก็ควรจะอยู่ในcompile link
อายุการใช้งาน

4
+1 ถึงความคิดเห็นด้านบน; นี่เป็นคำอธิบายที่กระชับที่สุดที่ฉันค้นพบ มันตรงกับการกวดวิชาที่ผมพบที่นี่
Benny Bottema

18

นี่คือจากการพูดคุยของ Misko เกี่ยวกับคำสั่ง http://youtu.be/WqmeI5fZcho?t=16m23s

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


10

สายไปด้ายเล็กน้อย แต่เพื่อประโยชน์ของผู้อ่านในอนาคต:

ฉันเจอวิดีโอต่อไปนี้ซึ่งอธิบายการคอมไพล์และลิงก์ใน Angular JS ในรูปแบบที่ยอดเยี่ยมมาก:

https://www.youtube.com/watch?v=bjFqSyddCeA

มันจะไม่พอใจที่จะคัดลอก / พิมพ์ในเนื้อหาทั้งหมดที่นี่ ฉันจับภาพหน้าจอสองสามภาพจากวิดีโอซึ่งอธิบายขั้นตอนการคอมไพล์และลิงค์ทุกขั้นตอน:

รวบรวมและเชื่อมโยงใน Angular JS

รวบรวมและเชื่อมโยงในเชิงมุม JS - คำสั่งซ้อน

ภาพหน้าจอที่สองค่อนข้างสับสนเล็กน้อย แต่ถ้าเราทำตามขั้นตอนการนับเลขมันจะค่อนข้างตรงไปข้างหน้า

รอบแรก: "รวบรวม" ได้รับการดำเนินการในทุกคำสั่งก่อน
รอบที่สอง: "Controller" และ "Pre-Link" ได้รับการดำเนินการ (เพียงครั้งเดียวหลังจากนั้นอีกครั้ง) รอบที่สาม: "Post-Link" ได้รับการดำเนินการในลำดับที่กลับกัน (เริ่มต้นจากภายในสุด)

ต่อไปนี้เป็นรหัสซึ่งแสดงให้เห็นข้างต้น:

var app = angular.module ('แอป', []);

app.controller ('msg', ['$ scope', ฟังก์ชั่น ($ scope) {

}]);

app.directive ('ข้อความ', ฟังก์ชัน ($ interpolate) {
    กลับ{

        รวบรวม: ฟังก์ชั่น (tElement, tAttributes) { 
            console.log (tAttributes.text + "-In คอมไพล์ .. ");
            กลับ {

                ก่อน: ฟังก์ชั่น (ขอบเขต, iElement, iAttributes, คอนโทรลเลอร์) {
                    console.log (iAttributes.text + "-In pre .. ");
                }

                โพสต์: ฟังก์ชั่น (ขอบเขต, iElement, iAttributes, คอนโทรลเลอร์) {
                    console.log (iAttributes.text + "-In Post .. ");
                }

            }
        }

        ตัวควบคุม: ฟังก์ชัน (ขอบเขต $, องค์ประกอบ $, $ attrs) {
            console.log ($ attrs.text + "-In controller .. ");
        }

    }
});
<body ng-app="app">
<div ng-controller="msg">
    <div message text="first">
        <div message text="..second">
            <div message text="....third">

            </div>              
        </div>  
    </div>
</div>

UPDATE:

ส่วนที่ 2 ของวิดีโอเดียวกันมีให้ที่นี่: https://www.youtube.com/watch?v=1M3LZ1cu7rw วิดีโออธิบายเพิ่มเติมเกี่ยวกับวิธีการแก้ไข DOM และจัดการเหตุการณ์ในระหว่างกระบวนการคอมไพล์และลิงก์ของ Angular JS ในตัวอย่างง่ายๆ .


ใช้compileและpostแก้ไข DOM ก่อนที่จะแก้ไขtemplateส่วนหนึ่งจากคำสั่งของผู้จัดจำหน่าย
jedi

6

สองขั้นตอน: รวบรวมและเชื่อมโยง

รวบรวม:

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

Link:

เมื่อองค์ประกอบถูกเชื่อมโยงต้นไม้ DOM จะแตกที่จุดสาขาในต้นไม้ DOM และเนื้อหาจะถูกแทนที่ด้วยอินสแตนซ์ที่รวบรวม (และเชื่อมโยง) ของแม่แบบ เนื้อหาที่แทนที่เดิมจะถูกลบทิ้งหรือในกรณีของการแปลงข้อมูลให้เชื่อมโยงกลับเข้าไปในเทมเพลตอีกครั้ง ด้วย Transclusion ทั้งสองชิ้นจะถูกเชื่อมโยงกลับเข้าด้วยกัน (เหมือนโซ่ที่มีแม่แบบอยู่ตรงกลาง) เมื่อเรียกฟังก์ชันการเชื่อมโยงแม่แบบได้ถูกผูกไว้กับขอบเขตและเพิ่มเป็นลูกขององค์ประกอบ ฟังก์ชั่นลิงค์เป็นโอกาสของคุณในการจัดการ DOM ต่อไปและตั้งค่าฟังการเปลี่ยนแปลง


3

คำถามนี้เก่าโดยฉันต้องการสรุปสั้น ๆ ซึ่งอาจช่วย:

  • รวบรวมเรียกครั้งเดียวสำหรับคำสั่งอินสแตนซ์ทั้งหมด
  • รวบรวมจุดประสงค์หลักคือการส่งคืน / สร้างลิงค์ (และอาจจะก่อน / หลัง) ฟังก์ชั่น / วัตถุ คุณยังสามารถเริ่มต้นสิ่งที่แบ่งปันระหว่างอินสแตนซ์ของคำสั่ง
  • ในความเห็นของฉัน "ลิงก์" เป็นชื่อที่สับสนสำหรับคุณสมบัตินี้ ฉันต้องการ "แสดงผลล่วงหน้า"
  • ลิงก์ถูกเรียกสำหรับแต่ละอินสแตนซ์คำสั่งและจุดประสงค์ของมันคือเพื่อเตรียมการเรนเดอร์ของคำสั่งใน DOM

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