การขยายคำสั่งเชิงมุม


114

ฉันต้องการแก้ไขเล็กน้อยกับคำสั่งของบุคคลที่สาม (โดยเฉพาะAngular UI Bootstrap ) ฉันเพียงแค่ต้องการเพิ่มขอบเขตของpaneคำสั่ง:

angular.module('ui.bootstrap.tabs', [])
.controller('TabsController', ['$scope', '$element', function($scope, $element) {
  // various methods
}])
.directive('tabs', function() {
  return {
    // etc...
  };
})
.directive('pane', ['$parse', function($parse) {
  return {
    require: '^tabs',
    restrict: 'EA',
    transclude: true,
    scope:{
      heading:'@',
      disabled:'@' // <- ADDED SCOPE PROPERTY HERE
    },
    link: function(scope, element, attrs, tabsCtrl) {
      // link function
    },
    templateUrl: 'template/tabs/pane.html',
    replace: true
  };
}]);

แต่ฉันยังต้องการให้ Angular-Bootstrap อัปเดตอยู่เสมอด้วย Bower ทันทีที่เรียกใช้bower updateฉันจะเขียนทับการเปลี่ยนแปลงของฉัน

แล้วฉันจะขยายคำสั่งนี้แยกต่างหากจากส่วนประกอบ bower นี้ได้อย่างไร


2
วิธีที่สะอาดจะใช้$provide.decorator()ดูคำตอบของฉันด้านล่าง
Eliran Malka

คำตอบ:


96

อาจเป็นวิธีที่ง่ายที่สุดในการแก้ปัญหานี้คือการสร้างคำสั่งในแอปของคุณโดยใช้ชื่อเดียวกับคำสั่งของบุคคลที่สาม คำสั่งทั้งสองจะทำงานและคุณสามารถระบุลำดับการรันโดยใช้priorityคุณสมบัติ (ลำดับความสำคัญสูงกว่าจะรันก่อน)

คำสั่งทั้งสองจะใช้ขอบเขตร่วมกันและคุณสามารถเข้าถึงและแก้ไขขอบเขตของคำสั่งบุคคลที่สามผ่านlinkวิธีการของคำสั่งของคุณ

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

อ่านเพิ่มเติม: https://github.com/angular/angular.js/wiki/Dev-Guide%3A-Understand-Directives

หมายเหตุ:คำตอบก่อนหน้าของฉันคือการแก้ไขบริการของบุคคลที่สามไม่ใช่คำสั่ง


3
ขอบคุณ @ sh0ber นี่คือสิ่งที่ฉันต้องการจริงๆ และคำตอบก่อนหน้าของคุณช่วยฉันเช่นกันเรื่องบริการของบุคคลที่สาม
Kyle

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

2
@Ciel เห็นได้ชัดว่าข้อมูล API คำสั่งถูกย้ายไปยัง$compileเอกสารที่นี่
Dan

60

TL; DR - อ้างท่าสาธิต!


     Big Demo Button     
 


ใช้$provide's decorator()ไป, ดี, ตกแต่งสั่งของบุคคลที่สาม

ในกรณีของเราเราสามารถขยายขอบเขตของคำสั่งได้ดังนี้:

app.config(function($provide) {
    $provide.decorator('paneDirective', function($delegate) {
        var directive = $delegate[0];
        angular.extend(directive.scope, {
            disabled:'@'
        });
        return $delegate;
    });
});

ขั้นแรกเราขอตกแต่งpaneคำสั่งโดยส่งชื่อของมันเชื่อมต่อกับDirectiveอาร์กิวเมนต์แรกจากนั้นเราดึงมันมาจากพารามิเตอร์การเรียกกลับ (ซึ่งเป็นอาร์เรย์ของคำสั่งที่ตรงกับชื่อนั้น)

เมื่อเราได้มันมาแล้วเราสามารถรับวัตถุขอบเขตและขยายได้ตามต้องการ สังเกตว่าทั้งหมดนี้จะต้องทำในconfigบล็อก

บันทึกบางส่วน

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

  • JeetendraChauhan อ้างว่า (ฉันยังไม่ได้ทดสอบ) ว่าโซลูชันนี้จะใช้ไม่ได้ในเวอร์ชัน 1.13


1
ฉันขอแนะนำให้คุณตอบคำถามของ @ sh0ber ก่อน (สร้างคำสั่งอื่นสำหรับการเปล่งเหตุการณ์)
Eliran Malka

2
หมายเหตุสั้น ๆ เกี่ยวกับคำตอบนี้ (ซึ่งใช้งานได้ดี) 'คำสั่ง' ใน 'paneDirective' มีจุดประสงค์ ;-) ฉันใช้เวลาสักพักก่อนที่จะพบว่า: stackoverflow.com/questions/19409017/…ดูที่ยอมรับ ตอบ.
Roy Milder

2
สวัสดี @EliranMalka ตรวจสอบ plunker ฉันplnkr.co/edit/0mvQjHYjQCFS6joYJdwK หวังว่านี้จะช่วยให้ใครบางคน
Jeetendra ชัวฮาน

1
ลิงก์ไปยังใช้งานdecorator()ไม่ได้ (อัปเดตเป็นdocs.angularjs.org/api/auto/service/$provide#decorator )
Chris Brown

1
@EliranMalka ใช่bindToControllerเปิดตัวใน v1.3 แต่โปรดทราบว่านี่ไม่ถือเป็นทางเลือกอื่นสำหรับกรณีเฉพาะที่มีการตั้งค่าคำสั่งเดิมกับbindToControllerคุณสมบัติ ความคิดที่ดีฉันจะโพสต์สิ่งนี้เป็นคำตอบ :)
gilad mayani

8

แม้ว่านี่จะไม่ใช่คำตอบโดยตรงสำหรับคำถามของคุณ แต่คุณอาจต้องการทราบว่าเวอร์ชันล่าสุด (เป็นหลัก) ของhttp://angular-ui.github.io/bootstrap/ ได้เพิ่มการสนับสนุนสำหรับการปิดใช้งานแท็บ คุณสมบัตินี้ถูกเพิ่มผ่าน: https://github.com/angular-ui/bootstrap/commit/2b78dd16abd7e09846fa484331b5c35ece6619a2


+1 สำหรับหัวขึ้น ดีแล้วที่รู้. ฉันเดาว่า angular-bootstrap ของ bower และส่วนประกอบ bootstrap ของ angular-ui ไม่ตรงกัน
Kyle

6

อีกวิธีหนึ่งที่คุณสร้างคำสั่งใหม่ที่ขยายโดยไม่ต้องแก้ไขคำสั่งเดิม

การแก้ปัญหาคล้ายกับโซลูชันมัณฑนากร:

สร้างคำสั่งใหม่และฉีดเป็นการพึ่งพาคำสั่งที่คุณต้องการขยาย

app.directive('extendedPane', function (paneDirective) {

  // to inject a directive as a service append "Directive" to the directive name
  // you will receive an array of directive configurations that match this 
  // directive (usually only one) ordered by priority

  var configExtension = {
     scope: {
       disabled: '@'
     }
  }

  return angular.merge({}, paneDirective[0], configExtension)
});

ด้วยวิธีนี้คุณสามารถใช้คำสั่งดั้งเดิมและเวอร์ชันเพิ่มเติมในแอปเดียวกันได้


2
นี่เป็นสิ่งที่ยอดเยี่ยมสิ่งที่ฉันต้องการเพื่อขยายคำสั่งขอบเขตการแยกด้วยตัวแปรของฉันเอง !! ฉันพบว่า angular.extend ไม่ได้คัดลอกวัตถุในระดับลึกดังนั้นสิ่งนี้จึงแทนที่วัตถุขอบเขตของ paneDirective ด้วยวัตถุนี้ อีกทางเลือกหนึ่งคือ angular.merge ซึ่งจะเก็บขอบเขตเดิมจาก PaneDirective และตัวแปรเพิ่ม / ผสานที่กำหนดไว้ที่นี่
mathewguest

1
ใช่angular.mergeควรใช้แล้วฉันจะอัปเดตตัวอย่าง
kidroca

1

นี่คืออีกวิธีหนึ่งสำหรับสถานการณ์ที่แตกต่างกันของการขยายการผูกกับคำสั่งที่มีbindToControllerคุณสมบัติ

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

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