การทำความเข้าใจกับตัวเลือกรวมของข้อกำหนดคำสั่ง?


195

ฉันคิดว่านี่เป็นหนึ่งในแนวคิดที่ยากที่สุดสำหรับฉันที่จะเข้าใจด้วยคำสั่งของ angularjs

เอกสารจากhttp://docs.angularjs.org/guide/directiveพูดว่า:

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

  • true - ไม่รวมเนื้อหาของคำสั่ง
  • 'องค์ประกอบ' - รวมองค์ประกอบทั้งหมดรวมถึงคำสั่งใด ๆ ที่กำหนดไว้ที่ลำดับความสำคัญต่ำกว่า

มันบอกว่ามักจะใช้กับtransclude ngTranscludeแต่ตัวอย่างจากเอกสารของngTranscludeไม่ได้ใช้ngTranscludeคำสั่งเลย

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


FYI ... ลิงก์กำลังทำงานอย่างน้อยตอนนี้
Sandy

คำตอบ:


518

พิจารณาคำสั่งที่เรียกว่าmyDirectiveในองค์ประกอบและองค์ประกอบนั้นล้อมรอบเนื้อหาอื่น ๆ สมมติว่า:

<div my-directive>
    <button>some button</button>
    <a href="#">and a link</a>
</div>

หากmyDirectiveใช้เทมเพลตคุณจะเห็นว่าเนื้อหาของ<div my-directive>จะถูกแทนที่ด้วยเทมเพลตคำสั่งของคุณ ดังนั้นมี:

app.directive('myDirective', function(){
    return{
        template: '<div class="something"> This is my directive content</div>'
    }
});

จะส่งผลให้เรนเดอร์นี้:

<div class="something"> This is my directive content</div> 

ขอให้สังเกตว่าเนื้อหาขององค์ประกอบเดิมของคุณ<div my-directive> จะหายไป (หรือดีกว่ากล่าวคือแทนที่) ดังนั้นบอกลาเพื่อนเหล่านี้:

<button>some button</button>
<a href="#">and a link</a>

ดังนั้นสิ่งที่ถ้าคุณต้องการที่จะให้คุณ<button>...และ<a href>...ใน DOM หรือไม่ คุณจะต้องมีสิ่งที่เรียกว่าการถ่ายโอน แนวคิดง่ายสวย: รวมเนื้อหาจากสถานที่หนึ่งไปยังอีก ดังนั้นตอนนี้คำสั่งของคุณจะมีลักษณะเช่นนี้:

app.directive('myDirective', function(){
    return{
        transclude: true,
        template: '<div class="something"> This is my directive content</div> <ng-transclude></ng-transclude>'
    }
});

สิ่งนี้จะทำให้:

<div class="something"> This is my directive content
    <button>some button</button>
    <a href="#">and a link</a>
</div>. 

สรุปแล้วคุณใช้ transclude โดยทั่วไปเมื่อคุณต้องการเก็บเนื้อหาขององค์ประกอบเมื่อคุณใช้คำสั่ง

ตัวอย่างรหัสของฉันคือที่นี่ นอกจากนี้คุณยังจะได้รับประโยชน์จากการดูนี้


12
ดูเหมือนว่าพวกเขาเปลี่ยนการใช้งานเล็กน้อย อย่างน้อยในเวอร์ชัน> = 1.2.9 เนื้อหาจากแม่แบบจะไม่ถูกเพิ่มลงในเนื้อหาที่แสดงผล ดูคำตอบของ @ TechExplorer ด้านล่าง
Tarjei Romtveit

20
คำตอบที่ดีมาก ทางเหนือปกติ คุณมีตัวอย่างที่ดีและ "นี่คือเนื้อหาคำสั่งของฉัน" ทำให้ง่ายต่อการอ่านในเวอร์ชันที่แสดงผล ฉันไม่เข้าใจว่าทำไม Angular ต้องใช้คำศัพท์และแนวคิดที่ซับซ้อนและไม่ต้องมีตัวอย่างที่เข้าใจง่ายเช่นของคุณ +2
freeall

ไม่มีใครทราบว่าเนื้อหา transcluded สามารถอ้างถึงเขตขอบเขตแยกของ directive? มันกล่าวไว้ข้างต้นว่าบทสรุปเป็นพี่น้องไม่ใช่เด็กในขอบเขตแยก ... ดังนั้นฉันจึงคิดว่ามันเป็นไปไม่ได้ - แต่กำลังสงสัยว่ามีใครบางคนยืนยันหรือแจ้งให้เราทราบว่าเป็นไปได้หรือไม่
Simon Green

@UladzimirHavenchyk ขอบคุณพวกเขาย้ายวิดีโอไปยังที่อื่น ฉันแก้ไขลิงค์ตาม
odiseo

4
@odiseo คุณช่วยเขียน Angular docs ทั้งหมดให้เป็นภาษาอังกฤษได้ง่าย ๆ แบบนี้! +1 หลายอย่าง
Dan Hodson

76

ฉันคิดว่ามันสำคัญที่จะพูดถึงการเปลี่ยนแปลงในพฤติกรรมข้างต้นใน AngularJS เวอร์ชันใหม่ ฉันใช้เวลาหนึ่งชั่วโมงพยายามที่จะบรรลุผลลัพธ์ที่เหนือกว่าด้วย Angular 1.2.10

เนื้อหาขององค์ประกอบที่มี ng-transclude ไม่ได้ถูกผนวกเข้าด้วยกัน แต่ถูกแทนที่อย่างสมบูรณ์

ดังนั้นในตัวอย่างข้างต้นสิ่งที่คุณจะได้รับจาก 'transclude' คือ:

<div class="something">
    <button>some button</button>
    <a href="#">and a link</a>
</div>

และไม่

<div class="something"> This is my directive content
    <button>some button</button>
    <a href="#">and a link</a>
</div>

ขอบคุณ


สำหรับข้อมูลเพิ่มเติมเกี่ยวกับพฤติกรรมการเปลี่ยนแปลงในเชิงมุม 1.2 เห็นการเปลี่ยนแปลงeed299a
Mark Rajcok

37

สิ่งที่ TechExplorer พูดนั้นเป็นความจริง แต่คุณสามารถมีเนื้อหาทั้งสองอย่างโดยรวมแท็กคอนเทนเนอร์แบบง่ายๆ (เช่น div หรือ span) ในเทมเพลตของคุณด้วยแอตทริบิวต์ ng-transclude ซึ่งหมายความว่ารหัสต่อไปนี้ในเทมเพลตของคุณควรมีเนื้อหาทั้งหมด

<div class="something"> This is my directive content <div class="something" ng-transclude></div></div>

5
นั่นคือข้อมูลสำคัญที่ขาดหายไปกับคำตอบอื่น ๆ
Matheus

4
คำตอบนี้เพิ่มข้อมูลมากมาย ng-transcludeเป็นแอททริบิวต์ที่ทำหน้าที่เป็นตัวยึดตำแหน่งซึ่งเนื้อหานั้นจะถูกวางไว้
BeingSuman

5

จาก Wiki:

"ในวิทยาการคอมพิวเตอร์การรวมเป็นส่วนหนึ่งหรือทั้งหมดของเอกสารอิเล็กทรอนิกส์เป็นหนึ่งหรือมากกว่าหนึ่งเอกสารอื่น ๆ โดยการอ้างอิง"

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

http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-functions-inside-angularjs-directives-part-2-transclusion/


5

AngularJS Updated 1.6.6 เอกสารในขณะนี้มีคำอธิบายที่ดีกว่า

Transclude ใช้เพื่อสร้างคำสั่งที่ห่อองค์ประกอบอื่น ๆ

บางครั้งเป็นที่พึงปรารถนาที่จะสามารถส่งผ่านทั้งแม่แบบแทนที่จะเป็นสตริงหรือวัตถุ สมมติว่าเราต้องการสร้างองค์ประกอบ "กล่องโต้ตอบ" กล่องโต้ตอบควรจะสามารถห่อเนื้อหาใด ๆ

การทำเช่นนี้เราจำเป็นต้องใช้transcludeตัวเลือก ดูตัวอย่างด้านล่าง


script.js

angular.module('docsTransclusionExample', [])
.controller('Controller', ['$scope', function($scope) {
  $scope.name = 'Tobias';
}])
.directive('myDialog', function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    templateUrl: 'my-dialog.html',
    link: function(scope) {
      scope.name = 'Jeff';
    }
  };
});

index.html

<div ng-controller="Controller">
  <my-dialog>Check out the contents, {{name}}!</my-dialog>
</div>

ฉัน-dialog.html

<div class="alert" ng-transclude></div>

รวบรวมผลลัพธ์

<div ng-controller="Controller" class="ng-scope">
  <my-dialog class="ng-isolate-scope"><div class="alert" ng-transclude="">Check out the contents, Tobias!</div></my-dialog>
</div>

Transclude ทำให้เนื้อหาของคำสั่งด้วยตัวเลือกนี้มีการเข้าถึงขอบเขตด้านนอกของคำสั่งมากกว่าภายใน

นี่คือตัวอย่างในตัวอย่างก่อนหน้า โปรดสังเกตว่าเราได้เพิ่มฟังก์ชันลิงก์ใน script.js ที่กำหนดชื่อใหม่เป็น Jeff โดยปกติเราคาดหวังว่า {{name}} จะเป็น Jeff อย่างไรก็ตามเราเห็นในตัวอย่างนี้ว่าการผูก {{name}} ยังคงเป็นโทเบียส

วิธีปฏิบัติที่ดีที่สุด : ใช้เฉพาะtransclude: trueเมื่อคุณต้องการสร้างคำสั่งที่ล้อมเนื้อหาโดยพลการ


0

transclude: true หมายถึงการเพิ่มองค์ประกอบทั้งหมดที่กำหนดไว้ในคำสั่งของคุณด้วยองค์ประกอบแม่แบบของคำสั่งของคุณ

หาก transclude: false องค์ประกอบเหล่านี้จะไม่รวมอยู่ใน html สุดท้ายของคำสั่งเทมเพลตเฉพาะคำสั่งเท่านั้นที่แสดงผล

transclude: องค์ประกอบหมายถึงแม่แบบคำสั่งของคุณไม่ได้ใช้เฉพาะองค์ประกอบที่กำหนดไว้ในคำสั่งของคุณจะแสดงผลเป็น html

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

<my-directive><elements><my-directive>
<elements> is like <p>gratitude</p>
what i am talking about.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.