2015-06-25 38 views
0

我有一個angularjs指令,它將產生一個多選擇下拉菜單,並帶有一些複雜的模板。指令有一個孤立的範圍。根據下拉列表,點擊下拉菜單中名爲open的變量即可切換並調整可見性。當然,他的下拉菜單隻有在點擊DOM時纔會關閉。但是如果用戶一個接一個地點擊兩個下拉菜單,則兩個下拉菜單都保持打開。我們可以通過訪問其範圍並設置open的值來關閉兄弟姐妹下拉列表。 如何訪問源自相同指令的兄弟姐妹的隔離範圍?訪問由同一個角度指令導致的兄弟的隔離範圍

var directiveModule = angular.module('angular-drp-multiselect', []); 
directiveModule.directive('ngDropdownMultiselect', ['$filter', '$document', '$compile', '$parse', 
function ($filter, $document, $compile, $parse) { 

    return { 
     restrict: 'AE', 
     scope: { 
      selectedModel: '=', 
      options: '=', 
      extraSettings: '=', 
      events: '=', 
      searchFilter: '=?', 
      translationTexts: '=', 
      groupBy: '@'     
     }, 
     template: function (element, attrs) { 
      var checkboxes = attrs.checkboxes ? true : false; 
      var groups = attrs.groupBy ? true : false; 

      var template = '<div class="multiselect-parent btn-group dropdown-multiselect btn-block ">'; 
      template += '<button type="button" ng-disabled="getDisableStatus()" class="dropdown-toggle btn-block btn-leftAlign" ng-class="settings.buttonClasses" ng-click="HideAllOpenDropDowns();toggleDropdown($event)" ng-attr-title="{{getButtonTitle()}}">{{getButtonText()}}&nbsp;<span class="caret"></span></button>'; 
      template += '<ul class="dropdown-menu dropdown-menu-form" ng-data="{{open}}" ng-style="{display: open ? \'block\' : \'none\', height : settings.scrollable ? settings.scrollableHeight : \'auto\' }" style="overflow: scroll" >'; 
      template += '<li ng-hide="!settings.showCheckAll || settings.selectionLimit > 0"><a data-ng-click="selectAll()"> {{texts.checkAll}}</a>'; 
      ..... 
      element.html(template); 
     }, 
     link: function ($scope, $element, $attrs) { 
      var $dropdownTrigger = $element.children()[0]; 

      $scope.toggleDropdown = function() { 
      //here I need to access all siblings(generated from the same directive) scope , to control the visibility, by setting value for $scope.open 
      //I tried the following things 
      -------------------------------------- 
      //Attempt 1- not working 
      angular.forEach(angular.element($element.parent().parent().children()), function (value, key) { 
       var x = angular.element(value).scope(); 
        x.open = false; 
        //x.$apply(function() { 
         // x.open = false; 
        //}); 
        } 
      //Attempt 2- not working 
      angular.forEach(angular.element($(".multiselect-parent")), function (value, key) { 

       var menuElem = angular.element(value); 
       var menuElemScope = menuElem.scope(); 
       menuElemScope.$apply(function() { 
        menuElemScope.open = false; 
       }); 
      }); 


      -------------------------------------- 
       $scope.open = !$scope.open; 
      }; 
      ... 
      ... 

的HTML是

<div ng-app="multiSelectApp"> 
     <div ng-controller="MultiSelect"> 

     <div ng-dropdown-multiselect="" 
      extra-settings="DropDownSettings1" > 
     </div> 

     <div ng-dropdown-multiselect="" 
      extra-settings="DropDownSettings2" > 
     </div> 

     <div ng-dropdown-multiselect="" 
      extra-settings="DropDownSettings3" > 
     </div> 

     </div> 

     </div> 

回答

1

我覺得尋找DOM元素影響兄弟指令沒有角的方式。

您可以爲一個大的應用我會建議實施通信,而不是使用$rootScope服務做這樣的事情

link: function(element, attrs){ 
    .... 
    $rootScope.$on('openChanged', function(event, open){ 
     scope.isOpen = open; 
    }); 
    scope.toggleOpen = function(){ 
     var wasOpen = scope.isOpen; 
     $rootScope.$broadcast('openChanged', false); 
     scope.isOpen = !wasOpen; 
    } 

不過。

Fiddle用一個例子

UPDATE
關於服務實現。
我的建議是不要重新發明輪子和使用https://www.npmjs.com/package/angular-event-emitter

然而,有一個快速的解決方案,以實現像水木清華

.factory('broadcastService', function() { 
    var handlers = {}; 
    this.on = function (eventName, callback) { 
     var callbacks = handlers[eventName]; 
     if (!callbacks) { 
      handlers[eventName] = callbacks = []; 
     } 
     if (typeof callback === 'function' && callbacks.indexOf(callback) < 0) { 
      callbacks.push(callback); 
     } 
    }; 
    this.broadcast = function (eventName, args) { 
     var callbacks = handlers[eventName]; 
     if (callbacks) { 
      callbacks.map(function (handler) { 
       try { 
        handler({ 
         name: eventName 
        }, args); 
       } catch (ex) { 
        console.error(ex); 
       } 
      }); 
     } 
    } 
}) 
+0

真正偉大的..謝謝了很多。它的工作就像一個魅力..能否請您就如何這可以轉化爲一些見解一項服務? – amesh

+0

@amesh請參閱更新 –

+0

感謝您的快速回復..我是一個角度的新手。我正在研究它,並試圖理解相同的情況。 – amesh