2014-11-24 82 views
0

我需要两个兄弟指令来相互通信。第一个选择通过REST服务填充,当您从第一个下拉列表中选择一个值时,应该启用第二个下拉列表,并且下面的对象的子集应显示为其选项。兄弟姐妹指令之间的指令通信

例如:如果dropdown的第一个值= dog或dropdown = bird,那么第二个下拉列表应该只显示像意大利面条这样的SEries子集。但是,如果dropdown =乌龟,那么第二下拉应该显示所有的SEries。

如果无论如何要做到这一点,而不使用父母/子女的指导性沟通,这将是伟大的。

下面是对象类型:

$scope.Types = [{ 
    "id": "dog", 
    "name": "dog" 
    }, { 

    "id": "cat", 
    "name": "cat" 
    }, { 

    "id": "bird", 
    "name": "bird" 
    }, { 

    "id": "turtle", 
    "name": "turtle" 
    }]; 

下面是一系列对象:

$scope.Series = [{ 
    "id": "spaghetti", 
    "name": "spaghetti" 
    }, { 
    "id": "eggs", 
    "name": "eggs" 
    }]; 

})的” }];

这里是我2条指令:

.directive('selectBox', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     scope: false, 
     template: function (element, attrs) { 
      return '<div class="selectBox selector">' + '<select " class="form-control" name="' + attrs.name + '" ng-model="' + attrs.ngModel + '" ng-options="' + attrs.optexp + '"' + ' ng-disabled="' + attrs.selectdisabled + '"></select>' + '</div>'; 
     }   
    }; 
}) 

.directive('selectSeries', function() { 
    return { 
     restrict: 'E', 
     replace: true, 
     scope: false, 
     template: function(element, attrs) { 
     return '<div><select class="form-control" name="' + attrs.name + '" ng-model="' + attrs.ngModel + '" ng-options="series.id as series.name for series in series" ' + ' disabled="disabled" ></select></div>'; 

     }, 

     link: function (scope, el, attrs) { 
      scope.$watch('model.PlanType', function(value,b){ 

       if (value !== null){ 
        //angular.element(el).children('select').removeAttr('disabled'); 
        attrs.$set('ngOptions', 'series.id as series.name for series in series'); 

       } 

      },this); 
     } 

    }; 

}); 

这里是我的fiddle

+0

您可以尝试创建自定义发布/订阅。 [查看此答案](http://stackoverflow.com/questions/25274563/angularjs-communication-between-directives#answer-25274665) – PSL 2014-11-24 21:58:42

+0

@PSL我听说污染$ rootcope并不是一个好主意。这个应用程序将会相当大,如果从长远来看会导致问题,我不想开始污染$ rootcope。 – gerl 2014-11-25 16:34:46

+0

你没有污染执行事件总线的Rootcope(它不是特定于任何应用程序的业务逻辑),你基本上是扩展它,以便在内部创建一个新范围时,i,e'$ scope。$ new ()'这些方法在子范围中也是可用的并且共享相同的impl。好的污染是主观的,因为你放置了多少垃圾,特别是当你放置变量时,特定于应用程序业务逻辑的对象。另外如果你真的不想使用它,不要把它放在根作用域上使用管理pubsub的工厂。 – PSL 2014-11-25 17:00:37

回答

0

我不认为这是指令使用的一个很好的例子。在你的情况下,普通的选择和ng-change就足够了。就像这样:

<select ng-options="type.id as type.name for type in Types" ng-model="selectedType" ng-change="setEnabledSeries(selectedType)"></select> 

<select ng-options="series.id as series.name for series in EnabledSeries" ng-model="selectedSeries"></select> 

而在你的控制器:

$scope.setEnabledSeries = function(type) { 
    $scope.EnabledSeries = blah blah blah, according to type... 
} 

更新

有一个错字。它应该是selectedType而不是typeng-change的函数调用。请参阅正在工作的更新小提琴:http://jsfiddle.net/cp6kp6xb/1/

+0

我试过这样做,但视图不更新时,$ scope.EnabledSeries更新。继承人的代码http://jsfiddle.net/9so4kw7f/ – gerl 2014-11-25 17:47:11

+0

@gerl请找到更新的答案。 – 2014-11-25 20:12:30

1

不要试图强制指令之间的兄弟元素之间的直接通信。兄弟姐妹元素之间没有真正的联系。它们可以很容易地添加/删除,例如,当使用ng-if时,其次编译的元素指令可能在编译阶段甚至不符合DOM中的第一个元素。

如果你想让“兄弟姐妹”彼此交谈,而不是在外面泄漏他们的交流,把他们放在一个容器中创造一个范围是你最好的选择。为了进行更直接/复杂的交互,您可以创建一条指令,以便将其通信放置在其容器中。


创建,只是创建一个本地范围内的指令是一样简单:

.directive('scope', function() { 
    return { 
     scope: true, 
     link: function() {} 
    }; 
}); 

,然后你可以使用它

<div scope> 
    <select communicating-directive>...</select> 
    <select communicating-directive>...</select> 
</div> 

和当地分配到的范围不会泄漏在容器外面。