angularjs - 如何使兄弟指令通信工作(某些特定指令之间的通信)

标签 angularjs angularjs-directive

全部:

假设我有两个指令( dir1 和 dir2),它们都是隔离范围。从一些帖子中,我了解到我需要使用“require”来获取另一个指令的范围,但有一个问题让我非常困惑:

假设我使用 ng-repeat 生成了很多 dir1 和 dir2,我如何知道在某些 dir1 中,需要哪个特定的 dir2 的 Controller 范围(因为有很多 dir2 并且在我的理解中,dir2 Controller 中的所有这些范围都是彼此独立)?

例如:

app.directive("dir1", function(){
    var counter = 0;
    return {
        restrict:"AE",
        scope:{},
        template: "<button class='dir1_btn'>highlight dir2_"+(couter++)+" </button>",
        link:function(scope, EL, attrs){
             EL.find("button.dir1_btn").on("click", function(){
                 // How to let according dir2 know this click?
             })
        }
    }
}) 

app.directive("dir2", function(){
    var counter = 0;
    return {
        restrict:"AE",
        scope:{},
        template: "<span class='dir2_area'>This is dir2_"+(couter++)+" </span>",
        link:function(scope, EL, attrs){
             // Maybe put something here to listening the event passed from dir1?
        }
    }
}) 

和 html 类似(为了简单的目的,我只在那里放了 2 个,实际上它将由 ng-repeat 生成):

<dir1></dir1>
<dir2></dir2>
<dir1></dir1>
<dir2></dir2>

就像开关和灯一样,dir1 是根据灯 (dir2) 打开的开关(通过更改背景颜色)。

In actual project, what I want to do is angularJS directive version sidemenu and scrollContent, each item in sidemenu is a directive, click it will make according content(another directive) to auto scroll to top.

我想知道如何做到这一点?我知道这在 jQuery 中很容易,只是想知道如何将其挂接到 AngularJS 数据驱动模式中。

谢谢

最佳答案

这里要注意的最重要的一点是,我认为你想使用 ng-class由于您在 ng-repeat 中创建两个指令,我假设您正在迭代一个对象列表(即使它们是两个单独的 ng-repeat,如果您在两个对象中迭代相同的对象列表,它将起作用。JQuery 应该没有必要)?将 ngClass 对象附加到您迭代的每个对象,将其放在 dir2 中的 ng-class 属性上,然后授予 dir1 访问权限以更改它。如果你想为过渡设置动画,ngClass 提供动画钩子(Hook)。我的其余答案可能会有所帮助,尽管我现在想重做它,因为我想到了 ng-class。不过我现在必须回去工作了。我会关注反馈,如果您有疑问,我会尽力快速回答。

我认为可能有几种方法可以更好地完成您想要做的事情。目前尚不清楚为什么您的两个指令都需要具有隔离范围。随着我更多地使用 Angular,我发现虽然隔离范围是一种强大的技术,但最好避免过度使用它。

至于 require 指令属性,这篇文章explains how to make directives communicate via their controllers非常好。

我有两个可能的建议给你。 使其成为一个指令 为什么不能将模板合并到一起?

或者,如果我认为出于某种原因它们需要分开,您可以考虑在它们之间共享一个对象。

<div ng-repeat='obj in sharedDirObjs'>
  <dir1 shared-dir-obj='obj'></dir1>
  <dir2 shared-dir-obj='obj'></dir2>
</div>

app.controller('ctrl', function() {
  $scope.sharedDirObjs = [obj1, obj2, obj3]
});

app.directive("dir1", function(){
var counter = 0;
return {
    restrict:"AE",
    scope:{sharedDirObj : '='},
    template: "<button class='dir1_btn' ng-click='clickFn()'>highlight dir2_"+(couter++)+" </button>",
    link:function(scope, EL, attrs){
       var dir1vars...     
       scope.clickFn = function(){
             // dir1 logic...
             scope.sharedDirObj.dir2.clickFn(dir1vars...);
       };
    }
}}) 

app.directive("dir2", function(){
    var counter = 0;
    return {
        restrict:"AE",
        scope:{sharedDirObj : '='},
        template: "<span class='dir2_area'>This is dir2_"+(couter++)+" </span>",
        link:function(scope, EL, attrs){
             scope.sharedDirObj.dir2 = {};
             scope.sharedDirObj.dir2.clickFn(dir1vars...) {
                 // access to dir2 vars
             };
        }
    }})

类似地,您可以创建一个服务,其中包含通过注入(inject)服务共享的对象数组,并使用 ng-repeat 中的 $index 进行索引,或者您可以按照 PSL 建议使用 id 系统。请注意,我上面描述的解决方案可以使用隔离作用域,也可以不使用它,在任一或两个指令上使用 scope.$eval(attr.sharedObj); 。这个问题的答案provides a solid runthrough of when and why to use isolated scope.在任何情况下,最好不要像我上面展示的那样通过共享对象来传输函数,并且需要处理计时问题。更好的方法是在对象上存储属性并在 dir2 中对其设置范围。$watch。

关于angularjs - 如何使兄弟指令通信工作(某些特定指令之间的通信),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30739144/

相关文章:

angularjs - 用于 Bootstrap 弹出窗口的 Angular 指令

javascript - 用于 D3 图表的 AngularJS 指令

angularjs - 如何使用 Karma + Jasmine + AngularJS 在测试中运行通用代码?

javascript - 如何在 Angular 2 的 ui-router 中使用 `otherwise`?

javascript - 模态窗口的 Controller 可以访问父 Controller 中的函数吗

javascript - 如何在angularjs中动态创建变量名?

javascript - 创建 Angular Directive(指令)以重用代码 - 创建 html 时解析错误

javascript - 图像源未与指令内的范围变量绑定(bind)

javascript - 子指令访问每个父指令

javascript - 自定义指令可以用包含 ng-show 的模板替换它的元素吗?