簡體   English   中英

AngularJS指令到指令通信

[英]AngularJS Directive to directive communication

我有一個嵌套在另一個指令中的指令,如下面的小提琴所示。

http://jsfiddle.net/sriramr/T7W6T/3/

我的問題是:如果父指令中的變量更改了值,如何自動更新從父變量計算出的子指令中變量的值?

var myapp = angular.module('myApp',[]);
myapp.directive('parentDir', parentDir);
    function parentDir() {
        return {
            restrict:'E',
            controller: function eCtrl($scope) {
                $scope.parVal = 100;
                $scope.$on("event",function(e,data) {
                    console.log("emit")
                    $scope.parVal = 200;
                })

            },
            template:'<div><first-dir></first-dir</div>'
        }
    }

myapp.directive('firstDir', firstDir);
function firstDir() {
    return {
        restrict:'E',
        controller: function($scope) {
            //$scope.$watch('parVal',function() {
                $scope.childVal = $scope.parVal + 1;
            //})
            $scope.changeVal = function() {
                $scope.$emit("event")
            }
        },
        template:'<div>first Dir: {{parVal}} {{childVal}} <br /> <button ng-click="changeVal()">Change</button></div>'
    }
}

來自父指令的控制器范圍的變量parVal被傳遞給子指令的控制器。 child指令具有其自己的變量childVal ,即parVal + 1 我嘗試通過在子指令中發出一個事件來間接更改parVal的值。 正如預期的那樣, parVal的值會更改並反映在視圖中。 但是, childVal的值不會更改。

我可以在childVal使用$ watch查看parVal的更新值。 我還有其他方法可以做到嗎?

您可以通過幾種方式在這兩個指令之間共享代碼。

一種方法是利用firstDir原型繼承自parentDir 您已經使用parVal進行了此parVal ,但是您可能在從child指令中更新parVal遇到了問題。 一個簡單的解決方法是在父指令中創建一個更新函數。 這使您可以直接更新范圍。 示例: http//jsfiddle.net/T7W6T/4/
編輯:我不喜歡上面的方法,因為它緊密地結合了兩個指令,並且firstDir不能firstDir

另一種方法是創建共享服務。 角度服務是單例的,因此將其注入控制器中的任何地方都將與其他地方相同。 您可以輕松創建發布/訂閱機制。 只需確保在破壞訂戶范圍時清理訂戶。 這是我在指令和控制器之間共享的首選方式,因為您不會污染范圍。 請記住,與范圍相關的所有內容都會影響摘要。

最小發布/訂閱機制的示例代碼:

myapp.service('SharedService', function(){
    var listeners = [];
    return {
        publish: function(){
            angular.forEach(listeners, function(listener){
               listener.call(null); 
            });
        },
        subscribe: function(fn){
            listeners.push(fn);
        },
        unsubscribe: function(fn){
            var idx = listeners.indexOf(fn);
            if(idx > -1){
                 listeners.splice(idx,1);   
            }
        }
    }
});

您可以通過父指令與此交互,如下所示:

            var update = function(){
                $scope.parVal = 200;
            };

            SharedService.subscribe(update);

            $scope.$on("$destroy", function(){
               SharedService.unsubscribe(update); 
            });

而且child指令是唯一可以訪問該函數以發布給偵聽器的東西:

        $scope.updateParVal = function(){
            SharedService.publish();
        };

http://jsfiddle.net/T7W6T/5/

關於范圍繼承還是$emit更好,因此有一個很好的解釋: https : //stackoverflow.com/a/18179640/151445

關於服務方法,我通常不會看到的一件事是,您可以精確控制訂戶和發布者的綁定位置。 使用$scope.$emit$scope.$on ,任何具有范圍的人都可以為事件瘋狂。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM