使用ng-transclude和require指令通信的指令

时间:2015-08-23 17:44:42

标签: javascript angularjs angularjs-directive transclusion angularjs-ng-transclude

我有两个指令,让我们说:

angular.module('app').directive('directiveA', directiveA);

    function directiveA(){
        return {
            restrict: 'E',
            transclude: true,
            scope: {},
            templateUrl: 'directiveA.html',
            controller: function($scope){
                $scope.test="test data";
            }
        };
    }

第二个:

angular.module('app').directive('directiveB', directiveB);

function directiveB(){
    return {
        restrict: 'E',
        require: '^directiveA',
        transclude: true,
        scope: {},
        templateUrl: 'directiveB.html',
        link: function(scope, elem, attrs, directiveAController) {
            console.log("directiveB linked");
        }
    };
}

指令A的HTML:

<div>
<!-- something here -->
    <div ng-transclude></div>
</div>

指令B的HTML:

<div>{{test}}</div>

我想像这样使用它们:

<directive-a>
     <directive-b></directive-b>
</directive-a>

如何使用require和ng-transclude使它们相互通信并同时呈现两个模板?例如,我想在directiveB模板中从directiveA打印测试变量。我是指令和翻译的新手。

1 个答案:

答案 0 :(得分:0)

您可以选择进行沟通:

  1. $broadcast$emit取决于您的范围。见SO question。发送到$rootScope在这里很好,因为所有的孩子都可以听取事件。
  2. 使用回调函数(仅适用于子指令)。
  3. Observer pattern
  4. 请参阅下面的演示代码或此jsfiddle

    &#13;
    &#13;
    angular.module('demoApp', [])
    	.controller('mainController', function($scope) {
    
    })
    	.service('interDirCom', function() {
        // observer pattern
        		var self = this;
        
    			angular.extend(this, {
                    subscribers: [],
                    subscriberCount: 0,
                newSubscriber: function(callback) {
                    return {
                        id: self.subscriberCount++,
                        notify: callback
                    };
                },
                subscribe: function(callback) {
                    //add listener
                    var subscriber = self.newSubscriber(callback);
                    self.subscribers.push(subscriber);
                },
                notify: function(message){
                    console.log('notify', this, self, self.subscribers);
                    angular.forEach(self.subscribers, function(subscriber) {
                        console.log(subscriber, message);
                        subscriber.notify(message);
                    });
                }
            });
        	//return service;
    	})
        .directive('directiveA', directiveA)
        .directive('directiveB', directiveB);
    
    function directiveA() {
        return {
            restrict: 'E',
            transclude: true,
            scope: {},
            templateUrl: 'directiveA.html',
            controller: function ($scope, $rootScope, interDirCom) {
                
                interDirCom.subscribe(function(message) {
                    //console.log('callback of subscriber called');
                	$scope.test2 = message;
                });
                
                $scope.test = "test data";
                this.test = 'hello from controller A in dir. B';
                
                $rootScope.$on('dirB:test', function(evt, data) {
                    console.log('received event', data);
                	$scope.test = data.message;
                });
                
                this.callback = function(message) {
                    $scope.test2 = message;
                };
            }
        };
    }
    
    function directiveB(interDirCom) {
        return {
            restrict: 'E',
            require: '^directiveA',
            transclude: true,
            scope: {},
            templateUrl: 'directiveB.html',
            link: function (scope, elem, attrs, directiveACtrl) {
                console.log("directiveB linked");
                //scope.test = "hello from B";
                scope.test = directiveACtrl.test;
                
                scope.$emit('dirB:test', {message: 'Hello from directive B in dir. A with a $emit to $rootScope'});
                directiveACtrl.callback('I am added with a callback function from dir. B. to dir. A');
                interDirCom.notify('Message from dir. B with observer pattern');
                console.log(interDirCom);
            }
        };
    }
    &#13;
    directive-b div{
        background-color: green !important;
    }
    
    directive-a>div{
        background-color: lightgray;
        border: 2px solid red;
    }
    &#13;
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="demoApp" ng-controller="mainController">
        <script type="text/ng-template" id="directiveA.html">
            <div>
                <h1>Directive A</h1>
                {{test}}<br/>
                {{test2}}
                <!-- something here -->
                <div ng-transclude></div>
            </div>
        </script>
        <script type="text/ng-template" id="directiveB.html">
            <div>
            <h1>Directive B</h1>
            <div>{{test}}</div>
                <div>{{test2}}</div>
            </div>
        </script>
        <directive-a>
            <directive-b></directive-b>
        </directive-a>
    </div>
    &#13;
    &#13;
    &#13;