2014-04-07 19 views
5

Tôi đang cố gắng liên lạc giữa chỉ thị gốc và chỉ thị con lồng nhau của nó và cách khác. Tôi đã quản lý để đạt được điều này bằng cách sử dụng $ broadcast và $ emit, nhưng vì tôi đang chuyển một số đối số cho các chỉ thị, tôi đã phải tạo ra phạm vi cô lập trên các chỉ thị của tôi, vì vậy để phát $/$ emit công việc tôi phải phát 'lên một mức' trên phạm vi phụ huynh (phạm vi. $ parent. $ broadcast). Bây giờ chương trình phát sóng không chỉ tiếp tục với đứa trẻ lồng nhau, mà còn cho tất cả các chỉ thị ở cùng cấp độ mà tôi không muốn. Tôi đã tạo một plunker để hiển thị vấn đề, here. Điều tôi cần là khi nhấn một trong các nút, chỉ hướng dẫn trẻ em mới nhận được tin nhắn quảng bá và ngược lại. Tôi có thiếu một cái gì đó, hoặc là điều này không thể khi sử dụng phạm vi bị cô lập?Giao tiếp giữa các chỉ thị lồng nhau

Trong HTML của tôi:

<body ng-app="myApp"> 
    <directive1 data-title="Click me to change name"> 
    <directive2 data-name="John Smith"></directive2> 
    </directive1> 

    <directive1 data-title="Click me to change this other name"> 
    <directive2 data-name="Gordon Freeman"></directive2> 
    </directive1> 
</body> 

Chỉ thị 1:

<div> 
    <button ng-click="changeName()">{{title}}</button> 
    <div ng-transclude></div> 
</div> 

Chỉ thị 2:

<div> 
    <h2>{{name}}</h2> 
</div> 

chỉ thị của tôi:

myApp.directive('directive1', function(){ 
    return { 
    restrict: 'E', 
    replace: true, 
    templateUrl: 'Directive1.html', 
    transclude: true, 
    scope: { 
     title: '@' 
    }, 
    link: function(scope, elem){ 
     scope.changeName = function() { 
     scope.$parent.$broadcast('ChangeName'); 
     }; 

     scope.$parent.$on('NameChanged', function(event, args){ 
     scope.title = 'Name changed to ' + args; 
     }); 
    } 
    } 
}); 


myApp.directive('directive2', function(){ 
    return { 
    restrict: 'E', 
    replace: true, 
    templateUrl: 'Directive2.html', 
    scope: { 
     name: '@' 
    }, 
    link: function(scope, elem){ 
     scope.$on('ChangeName', function(event, args){ 
     scope.name = 'Adam West'; 

     scope.$emit('NameChanged', 'Adam West'); 
     }); 
    } 
    } 
}); 
+1

có một cái nhìn ở đây http://programmers.stackexchange.com/questions/223006/communication-between-nested-directives – user902383

+0

Cảm ơn, nhưng tôi không nghĩ rằng bất kỳ đó là áp dụng ở đây; Tôi không muốn tiêm dịch vụ (dường như quá mức). Chỉ thị cha mẹ yêu cầu không hoạt động (tôi giả sử vì việc sử dụng transclude), và thực thi biểu thức trong phạm vi cha mẹ (thông qua &) sẽ hoạt động, nhưng chỉ có một cách (chức năng thực thi chỉ thị lồng nhau trên chỉ thị cha). –

+1

bạn có xem xét việc đặt id cho chỉ thị không, chỉ có chỉ thị bên trong có cùng id như chỉ thị bên ngoài sẽ xử lý sự kiện. hãy xem ví dụ này http://plnkr.co/edit/dqGPDMF3f8NLBH4GX6dO?p=preview – user902383

Trả lời

4

Có 5 cách chính để liên lạc giữa các chỉ thị:

1) Dịch vụ phổ biến.

Đây không phải là một giải pháp tốt cho bạn bởi vì dịch vụ luôn là những người độc thân và bạn muốn có nhiều chỉ thị duy nhất. Bạn chỉ có thể sử dụng một dịch vụ nếu bạn duy trì một từ điển của cha mẹ và trẻ em trong dịch vụ và quản lý định tuyến các cuộc gọi đến cha mẹ/con có liên quan, đó là vấn đề tương tự bạn đang sử dụng sự kiện.

2) Sự kiện.

Nếu bạn không thể giới hạn sự kiện vào phần chính xác của DOM/cây thông qua phát sóng từ nút phải, bạn sẽ phải thêm số nhận dạng duy nhất vào sự kiện. Trong trường hợp này, nếu bạn đang phát sóng từ gốc và/hoặc nhiều trẻ em đang nhận được thông báo, hãy cung cấp cho mỗi phụ huynh/con một số nhận dạng duy nhất và thêm số này vào phát/phát/bật. Đây không phải là một giải pháp khá, nhưng nó sẽ hoạt động.

3) Ràng buộc một chiều.

Gắn kết '&' trong một phạm vi riêng biệt cho phép bạn chuyển các hàm gốc vào một đứa trẻ. Sau đó, trẻ có thể gọi các hàm này trên phạm vi gốc để thông báo cho phụ huynh về các thay đổi. Điều này là rất tốt cho giao tiếp con - cha mẹ nhưng không đi theo cách khác. Bạn có thể kết hợp giải pháp này với phát sóng sự kiện từ cha mẹ để giao tiếp với trẻ.

4) Liên kết hai chiều.

Đôi khi bạn có thể sử dụng thuộc tính trên một phạm vi riêng biệt để chuyển thông tin hoặc cờ lại và cho giữa cha và con. Điều này không làm việc trong ví dụ của bạn bởi vì cha mẹ không biết bất cứ điều gì về con của mình kể từ khi đứa trẻ được tiêm thông qua việc chuyển đổi.

5) require bộ điều khiển chính.

Chỉ thị có thể sử dụng thuộc tính require để chỉ định rằng một chỉ thị khác bắt buộc phải tồn tại dưới dạng cha mẹ hoặc trên cùng một phần tử.Bạn không thể yêu cầu chỉ thị anh chị em. Các chỉ thị bắt buộc phải có bộ điều khiển được xác định. Bộ điều khiển sau đó được chuyển đến chức năng liên kết (hoặc biên dịch) và bạn có thể gọi các chức năng trên bộ điều khiển. Điều này có thể được sử dụng để cho phép giao tiếp giữa các chỉ thị. Trong ví dụ của bạn, nếu directive2 yêu cầu directive1 bạn có thể thiết lập các chức năng như addChild() cho bộ điều khiển. Sau đó, con (directive2) sẽ thêm chính nó vào phụ huynh có thể cập nhật/gọi tất cả các trẻ em khi changeName được gọi.

myApp.directive('directive1', function(){ 
    return { 
    // ... 
    controller: function($scope) { 
     $scope.children = []; 
     this.addChild = function(child) { 
     $scope.children.push(child); 
     } 
    }, 
    link: function(scope, elem){ 
     scope.changeName = function() { 
     _.each(scope.children, function(child) { 
      child.setName('Adam West'); 
     }; 
     }; 
    }, 
    } 
}); 


myApp.directive('directive2', function(){ 
    return { 
    // ... 
    require: "^directive1", // require directive1 as a parent or on same element 
    link: function(scope, elem, attributes, directive1Controller){ 
     child = { 
     setName: function(name) { 
      scope.name = name; 
     }, 
     }; 

     directive1Controller.addChild(child); 
    } 
    } 
}); 
Các vấn đề liên quan