2014-11-24 61 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> 

和當地分配到的範圍不會泄漏在容器外面。