Angularjs 如何使指令与其父控制器或其同级指令对话

Angularjs 如何使指令与其父控制器或其同级指令对话,angularjs,angularjs-directive,Angularjs,Angularjs Directive,全部: 我对Angular是个新手,仍在试图弄清楚所有的概念。当我学习设计指导时,有一件事让我困惑: 我要创建的是一个image指令(我称之为“imgloader”指令),它具有从父控制器传递的属性imgurl(为了简单起见,让它成为“主”控制器),当单击此图像时,它将显示自定义样式的工具提示,以显示其链接。当该指令与ng repeat一起使用时,所有具有相同imgurl的其他imgloader应高亮显示其边框,以便用户可以轻松知道有多少图像是相同的 结构可能如下所示: <body ng-

全部:

我对Angular是个新手,仍在试图弄清楚所有的概念。当我学习设计指导时,有一件事让我困惑:

我要创建的是一个image指令(我称之为“imgloader”指令),它具有从父控制器传递的属性imgurl(为了简单起见,让它成为“主”控制器),当单击此图像时,它将显示自定义样式的工具提示,以显示其链接。当该指令与ng repeat一起使用时,所有具有相同imgurl的其他imgloader应高亮显示其边框,以便用户可以轻松知道有多少图像是相同的

结构可能如下所示:

<body ng-controller="main">
    <imgloader ng-repeat="url in imgurls track by $index" imgurl="url"></imgloader>
</body>

我考虑的imgloader指令如下(请修改以使其正确):

app.directive(“imgloader”,function(){
返回{
限制:“E”,
作用域:{imgurl:=“},
控制器:函数($scope){
$scope.showurl_和_hilightother=函数(){
//我需要知道怎么做
}
},
模板:“”
}
})
我正在考虑使用$emit让其他指令知道这个事件,但我不确定这是否是正确的方法(这似乎不需要$rootscope或从外部传递的某个引用范围对象),有人能给出如何实现它的建议(或代码演示)吗


谢谢

如果您希望在父级和指令之间进行通信,有几个选项。如果一个父指令中包含多个指令,并且希望来回传递信息。。。我建议继承父指令控制器,并使用其数据从每个指令调用控制器

既然你有一些标记

app.directive("imgloader", function(){
    return {
        restrict:"E",
        scope:{imgurl:"="},
        controller: function($scope){ 
            $scope.showurl_and_hilightother = function(){
                // I need to know how to do this
            }
        },
        template: "<img ng-src="{{imgurl}}" ng-click="showurl_and_hilightother()" />"
    }
})

您希望父指令具有每个子指令都可以继承的控制器

<div ng-controller="mainCtrl">

<parent-directive>
    <child-one-directive></child-one-directive>   
    <child-two-directive></child-two-directive>  
    <child-three-directive-rules-them-all></child-three-directive-rules-them-all>
</parent-directive>
.controller('parentDirectiveController',函数($scope){
$scope.messageFromChildDirective=“some message”;
this.updateParentMessage=函数(值){
$scope.messageFromChildDirective=值;
}
this.updateParentMessageThenPushToChildren=函数(值){
$scope.messageFromChildDirective=值;
$scope.$broadcast(“messageChanged”,值);
}
})
.directive('parentDirective',function(){
返回{
限制:'E',
是的,
控制器:“parentDirectiveController”,
链接:功能(范围、IELENT、iAttrs、ctrl){
scope.msg=函数(){
scope.messageFromChildDirective=“父消息”;
}
},
模板:“+”+
“来自父级的消息”+
“{{messageFromChildDirective}}”+
""
}
}) 
上面代码中的重要部分是,parentDirective将其控制器属性设置为“parentDirectiveController”,这是其他指令将继承的控制器,因此分配给控制器本身的任何内容都可以通过调用controller.whatever来访问

.controller('parentDirectiveController',function($scope) {

$scope.messageFromChildDirective = "some message";

this.updateParentMessage = function(value) {
     $scope.messageFromChildDirective = value;   
}

this.updateParentMessageThenPushToChildren = function(value) {
    $scope.messageFromChildDirective = value;
    $scope.$broadcast("messageChanged",value);
}
})

.directive('parentDirective', function() {

return {
    restrict: 'E',
    transclude: true,
    controller: 'parentDirectiveController',
    link: function(scope,iElement,iAttrs, ctrl) {


        scope.msg = function() {
            scope.messageFromChildDirective = "parent message";
        }


    },
    template: "<div class='parent'>" + "<div ng-transclude></div>" + 
              " <button ng-click='msg()'>Message from parent</button>"+
              "<div>{{messageFromChildDirective}}</div>"+
              "</div>"
}
}) 
.directive('childthreedirectiverules小',function(){
返回{
限制:'E',
要求:“^parentDirective”,
链接:功能(范围、IELENT、iAttrs、ctrl){
scope.directiveThreeName='Child Three Directive';
作用域:$on(“messageChanged”,handleMessageChanged);
函数handleMessageChanged(eventName、eventData){
scope.directiveThreeName=eventData;
}
scope.msgFromThree=函数(){
ctrl.updateParentMessageThenPushToChildren(“ChildThree指令”)
}
},
模板:“{directiveThreeName}}”
}
});
注意,在这个指令中,require属性设置为嵌套在其中的指令的名称。这将继承分配给该指令的控制器。控制器作为指令链接函数上的第四个参数传递,可以从那里调用连接到该控制器的任何内容

在这个范例中,正如您在指令中看到的,您可以使用一些值调用控制器函数,然后控制器可以广播一条消息。发出气泡后,广播将沿着层次结构向下进行,这样广播将仅由在控制器范围内创建的范围看到。可以在任何子指令上收听此广播,以便所有子指令都可以在收到更改通知时选择更新

我编写了一个基本的JSFIDLE,它演示了一个用于此目的的用例,其中两个子指令设置了它们自己的值和父值,但第三个子指令将更改传播到父指令以及所有其他子指令

我希望这有帮助


指令1
指令2
角度。模块('mayApp',[])
.controller('mayController',[function(){
var ctrl=this;
ctrl.pipeline1={
do:函数(){
if(ctrl.pipeline2.do instanceof函数)
ctrl.pipeline2.do();
}
};
ctrl.pipeline2={};
}])
.directive('mayDve1',[function(){
返回{
作用域:{dve1:'='},
链接:功能(范围、元素){
元素上('click',function()){
if(scope.dve1.do instanceof函数)
scope.dve1.do();
});
}
}
}])
.directive('mayDve2',[function(){
返回{
作用域:{dve2:'='},
链接:功能(范围、元素){
scope.dve2.do=函数(){
元素文本('单击指令1');
};
}
}
}]);

需要意识到,
ng repeat
已经为每个项目创建了一个子作用域。@charlietfl谢谢,但很抱歉我没听清楚你的意思,你能告诉我怎么做吗?谢谢,因为我不太理解指令,我将学习一点关于要求你满足的内容
.controller('parentDirectiveController',function($scope) {

$scope.messageFromChildDirective = "some message";

this.updateParentMessage = function(value) {
     $scope.messageFromChildDirective = value;   
}

this.updateParentMessageThenPushToChildren = function(value) {
    $scope.messageFromChildDirective = value;
    $scope.$broadcast("messageChanged",value);
}
})

.directive('parentDirective', function() {

return {
    restrict: 'E',
    transclude: true,
    controller: 'parentDirectiveController',
    link: function(scope,iElement,iAttrs, ctrl) {


        scope.msg = function() {
            scope.messageFromChildDirective = "parent message";
        }


    },
    template: "<div class='parent'>" + "<div ng-transclude></div>" + 
              " <button ng-click='msg()'>Message from parent</button>"+
              "<div>{{messageFromChildDirective}}</div>"+
              "</div>"
}
}) 
.directive('childThreeDirectiveRulesThemAll',function() {
return {
    restrict: 'E',
    require: '^parentDirective',
    link: function(scope,iElement,iAttrs, ctrl) {

        scope.directiveThreeName = 'Child Three Directive';
        scope.$on("messageChanged", handleMessageChanged);
        function handleMessageChanged(eventName, eventData) {
            scope.directiveThreeName = eventData;
        }
        scope.msgFromThree = function() { 
            ctrl.updateParentMessageThenPushToChildren("Child Three Directive") 
        }
    },
    template: "<div class='childThree' ng-click='msgFromThree()'>{{directiveThreeName}}</div>"
}
});
<div ng-app="mayApp" ng-controller="mayController as ctrl">
    <button may-dve1 dve1="ctrl.pipeline1">Directive 1</button>
    <div may-dve2 dve2="ctrl.pipeline2">Directive 2</div>
</div>

angular.module('mayApp',[])
.controller('mayController',[function(){
    var ctrl=this;
    ctrl.pipeline1={
        do:function(){
            if(ctrl.pipeline2.do instanceof Function)
                ctrl.pipeline2.do();
        }
    };
    ctrl.pipeline2={};
}])
.directive('mayDve1',[function(){
    return {
        scope:{dve1:'='},
        link:function(scope,element){
            element.on('click',function(){
                if(scope.dve1.do instanceof Function)
                    scope.dve1.do();
            });
        }
    }
}])
.directive('mayDve2',[function(){

    return {
        scope:{dve2:'='},
        link:function(scope,element){
            scope.dve2.do=function(){
                element.text('Directive 1 Clicked');
            };
        }
    }
}]);