2015-05-07 84 views
3

在AngularJS中,一條指令如何使用基於事件的通信($emit,$broadcast$on)與另一個具有隔離範圍的指令進行通信?我創建了兩個指令,當隔離範圍從第二個指令中刪除時,第一個指令可以使用emit來成功地與第二個指令進行通信。但是,當隔離範圍被添加到第二個時,通信就會中斷。通過隔離範圍的AngularJS基於事件的通信

var app = angular.module('myApp', []); 

app.directive("firstDir", function() { 
    return { 
    restrict: 'E', 
    controller: function($scope) { 
     $scope.set = function() { 
     $scope.$emit('MY_NEW_SEARCH', $scope.searchQuery); 
     }  
    }, 
    template: '<input type="text" ng-model="searchQuery"><button ng-click="set()">Change Value</button>' 
    }; 
}); 

app.directive("secondDir", function() { 
    return { 
    restrict : 'E', 
    scope: {}, 
    controller : function($scope) {  
     var _that = $scope; 
     $scope.$on('MY_NEW_SEARCH', function(e, data) { 
     _that.data = data; 
     }); 
     $scope.data = 'init value'; 
    } 
    }; 
}); 

我創建了一個Plunker來說明這個問題。您會注意到,如果您在第二個指令的指令定義對象中註釋掉「scope」屬性,通信將起作用:您可以在第一個指令的輸入框中鍵入一個字符串,按第一個指令,並且該字符串被傳遞給第二個指令,該指令將其顯示在視圖上。 (因爲它的立場,在Plunker壞了,因爲分離範圍問題,請參見行app.js文件19)。

http://plnkr.co/edit/AXUVX9zdJx1tApDhgH32

這裏是我的首要目標:原因我使用的是分離第二條指令的範圍是將範圍從範圍外分離出來。 (在我的項目中使用的實際「第二個指令」比這個玩具示例複雜得多,這就是必要的。)我知道AngularJS提供了將外部範圍映射到指令內部範圍的機制。我很好奇這些機制是否有助於映射事件通信事件。

如果答案證明孤立範圍對於基於事件的通信來說是不可逾越的,那麼在我已經說明的情況下完成指令到指令通信的最佳方式是什麼,同時仍然實現了我的目標?謝謝!

回答

5

這來自兩個問題。

1)第一個是因爲兩個指令在HTML中都處於同一級別,所以不能將一個事件從一個範圍移動到另一個範圍(除非它們具有相同的範圍,這是第二個指令不具有的範圍有一個孤立的範圍)。

爲了第一個指令聯繫第二,你可以通過$scope.$root.$broadcast取代$scope.$emit(其向上推移的範圍層次)(從根範圍向下進入其所有的孩子),或者乾脆$scope.$broadcast你的情況因爲這第一個指令範圍實際上是根範圍!

2)第二個問題是,你的第二個指令在隔離時並不像原樣那樣處理範圍轉換,所以在DOM中定義的更深的HTML不會共享該指令的隔離範圍,但是上面的那個沒有定義data

傳播的分離的範圍內的HTML的方法是通過使用該片段的功能link內:

link: function(scope, element, attrs, ctrl, transclude) { 
    transclude(scope, function(clone) { 
    element.append(clone); 
    }); 
} 

這裏是與兩個修復工作Plnker:

http://plnkr.co/edit/I9Vmutal2gfqyLIU0iAe?p=preview