0

我有两个指令,可以说:

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 打印测试变量。我是指令和嵌入的新手。

4

1 回答 1

0

您有一些选择来进行沟通:

  1. $broadcast$emit取决于您的范围。请参阅这个SO 问题。发送到$rootScope这里很好,因为所有孩子都可以监听事件。
  2. 使用回调函数(仅适用于子指令)。
  3. 观察者模式

请参阅下面或此jsfiddle中的演示代码。

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);
        }
    };
}
directive-b div{
    background-color: green !important;
}

directive-a>div{
    background-color: lightgray;
    border: 2px solid red;
}
<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>

于 2015-08-23T22:28:11.113 回答