我正在尝试通过他们的(内部定义的)控制器获得两个指令来相互通信,但我对角度很新,但仍然不清楚几件事情。
基本上,我只想要两个单独的指令,当你点击指令 A 中的一个元素时, B 中的一些函数会执行;我想根据 A 中的内容告诉 B 更新自己。到目前为止我得到了什么:
app.directive('A', function(){
return{
restrict: 'E',
require:'B',
templateUrl:'a.html',
link: function(scope, element, attr, bController){
//should I run B's behavior here?
//how? can't reach B's controller
},
controller: function(){
//or here?
//how do I access B's controller here?
},
controllerAs:'A'
};
});
app.directive('B', function(){
return{
restrict: 'E',
templateUrl:'b.html',
link: function(scope, element, attr){
},
controller: function(){
//here there'll be functions that manipulate
//elements inside this directive (B)
},
controllerAs:'B'
};
});
我收到错误,因为 A 正在尝试找到名为 B 的控制器,但它是一个指令:{{3 }}
另外,我应该操纵link
函数或指令控制器中的元素吗?即使在阅读之后,我对link
vs controller
仍然有点模糊;我看待它的方式:link
就像是各种构造函数,而控制器就是行为所在。
那么这是否意味着我总是将DOM操作放在控制器内部?
还有其他方法可以解决这个问题吗?我已经阅读了一些关于$scope
的内容,但仍然不完全清楚。
答案 0 :(得分:3)
您只能在父元素或同一元素中需要指令。你可能在A中使用B,反之亦然。
如果是这种情况,你有在另一个中使用的一个指令,你可以使用:require: '^A'
转到内部指令并要求外部指令。 ^
表示它可以是您父母的指示。
如果指令是兄弟姐妹,你可以构建一个第三个指令,将它们两者都包含在内,并且从两者内部都需要它,并且他们会使用这个媒介进行通信:
app.directive('C', function() {
return {
controller: function() {
this.registerPartyA = function(partyA) {
// ...
};
this.registerPartyB = function(partyB) {
// ...
};
}
}
});
然后从你的指令;
app.directive('B', function() {
return {
require: '^C',
link: function(scope, elm, attr, cCtrl) {
cCtrl.registerPartyB(...);
// maybe when user clicks you do
// cCtrl.aCtrl.doSomething()
}
};
});
如果它们无论如何,您仍然可以使用服务并在两个指令中注入服务,并将其用作常用位置。
最后,如果两个指令共享相同的范围(在同一个元素下,或者没有指令需要隔离/子范围),您可以直接在{{1}内部声明该方法并简单地从另一个指令中调用它:
$scope
最后一次通话,您可以使用$scope.$broadcast
and $scope.$emit
进行通信。
只要您符合要求,我就会按照我提及的顺序尝试。
答案 1 :(得分:1)
来自控制器的AngularJS文档:
使用控制器:
- 设置$ scope对象的初始状态。
- 向$ scope对象添加行为。
请勿使用控制器:
- 操纵DOM - 控制器应仅包含业务逻辑。 将任何表示逻辑放入控制器会显着影响 它的可测试性。 Angular对大多数情况和指令都有数据绑定 封装手动DOM操作。
- 格式输入 - 改为使用角度形式控件。过滤器输出 - 改为使用角度过滤器。
- 跨控制器共享代码或状态 - 改为使用角度服务。
- 管理其他组件的生命周期(例如,创建 服务实例)。
从AngularJS文档中获取指令:
指令可以被认为是DOM元素上的标记(例如 告诉AngularJS的属性,元素名称,注释或CSS类 HTML编译器($ compile)将指定的行为附加到该DOM 元素甚至转换DOM元素及其子元素。
所以,只是为了清楚地说明,不应该从不操纵控制器内的DOM。您应该始终使用指令link
函数来操作DOM。
如果您希望控制器彼此共享状态信息,则应考虑添加角度服务(文档here)。服务是一次实例化的对象,其状态在整个模块中保留。它们可以注入控制器。
另一种选择是实施一些$emit
和$on
事件提升者和听众。这将允许您使用事件通过控制器进行通信,以指示状态更改。这是另一篇SO帖子,它比我更好地解释了这一点:Working with $scope.$emit and $scope.$on。
希望这有帮助!