การสื่อสารระหว่างคำสั่งซ้อน


61

ดูเหมือนจะมีวิธีการสื่อสารค่อนข้างน้อยระหว่างคำสั่ง สมมติว่าคุณมีคำสั่งซ้อนกันซึ่งคำสั่งภายในต้องสื่อสารบางสิ่งกับภายนอก (เช่นถูกเลือกโดยผู้ใช้)

<outer>
  <inner></inner>
  <inner></inner>
</outer>

จนถึงตอนนี้ฉันมี 5 วิธีในการทำเช่นนี้

require: คำสั่งผู้ปกครอง

innerสั่งสามารถต้องouterสั่งซึ่งสามารถเปิดเผยวิธีการบางอย่างเกี่ยวกับการควบคุมของตน ดังนั้นในinnerความหมาย

require: '^outer',
link: function(scope, iElement, iAttrs, outerController) {
   // This can be passed to ng-click in the template
   $scope.chosen = function() {
     outerController.chosen(something);
   }
}

และในouterตัวควบคุมของคำสั่ง:

controller: function($scope) {
   this.chosen = function(something) {
   }
}

$emit เหตุการณ์

innerสั่งสามารถ$emitเหตุการณ์ที่สั่งสามารถตอบสนองต่อผ่านทางouter $onดังนั้นในinnerคอนโทรลเลอร์ของ directive:

controller: function($scope) {
  $scope.chosen = function() {
    $scope.$emit('inner::chosen', something);
  }
}

และในouterตัวควบคุมคำสั่ง:

controller: function($scope) {
  $scope.$on('inner::chosen, function(e, data) {
  }
}

ดำเนินการนิพจน์ในขอบเขตพาเรนต์ผ่าน &

ไอเท็มสามารถเชื่อมโยงกับนิพจน์ในขอบเขตพาเรนต์และเรียกใช้งานในจุดที่เหมาะสม HTML จะเป็นเช่น:

<outer>
  <inner inner-choose="functionOnOuter(item)"></inner>
  <inner inner-choose="functionOnOuter(item)"></inner>
</outer>

ดังนั้นinnerคอนโทรลเลอร์จึงมีฟังก์ชั่น 'InnerChoose' ที่สามารถเรียก

scope: {
  'innerChoose': '&'
},
controller: function() {
  $scope.click = function() {
    $scope.innerChoose({item:something});
  }
}

ซึ่งจะเรียก (ในกรณีนี้) ฟังก์ชั่น 'functionOnOuter' ในouterขอบเขตของคำสั่ง:

controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}

การสืบทอดขอบเขตในขอบเขตที่ไม่แยก

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

// scope: anything but a hash {}
controller: function() {
  $scope.click = function() {
    $scope.functionOnOuter(something);
  }
}

และในouterคำสั่ง:

controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}

โดยบริการฉีดเข้าไปทั้งภายในและภายนอก

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

คำถาม : อะไรคือข้อเสียและข้อได้เปรียบที่เป็นไปได้ของแต่ละรายการ


5
ฉันไม่อยากจะเชื่อเลยว่าฉันไม่เคยเห็นคำถามนี้มาก่อน ฉันขอขอบคุณตัวเลือกทั้งหมดที่คุณให้ไว้ หากคุณยังไม่ได้ดำเนินการคุณมีความคิดที่จะโพสต์คำถามนี้ใน stackoverflow หรือไม่? ฉันคาดหวังว่ามันจะได้รับแรงฉุดมากขึ้นใน stackoverflow
Mike Barlow - BarDev

โปรดดูข้อเสนอนี้ - softwareengineering.stackexchange.com/questions/344165/…
yellowblood

คำตอบ:


7

การตั้งค่าของฉันสำหรับกำหนด&แอตทริบิวต์ในขอบเขต directive เป็นหลักเพราะฉันดูscope: {}คำจำกัดความของคำสั่งเป็น API มันง่ายกว่ามากที่จะดูคำจำกัดความของขอบเขตคุณสมบัติเพื่อดูว่าข้อมูลใดที่คำสั่งต้องการให้ทำงานได้อย่างถูกต้องมากกว่าที่จะกัดเซาะลิงก์และฟังก์ชันควบคุมสำหรับ$emitเหตุการณ์ ', ฟังก์ชันขอบเขตที่สืบทอดมาหรือฟังก์ชันที่ใช้


1

ความคิดเห็นของฉัน:

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

ดังนั้น:

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

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