2016-01-05 65 views
1

我已經構建了一個指令來創建切換菜單,並且在同一頁面上多次使用同一個指令時遇到問題。同一頁面上的多個指令立即執行

這是指令:

function menuTrigger($document) { 
    return { 
     restrict: 'E', 
     scope: true, 
     link: function(scope, element, attrs) { 
      var 
       menuOpen = false, 
       elButton = angular.element(document.querySelectorAll(".menu-button")), 
       elContent = angular.element(document.querySelectorAll(".menu-content")), 
       elClose  = angular.element(document.querySelectorAll("[menu-close]")); 

      var 
       pos = attrs.pos, 
       style; 

      if (pos == 'tl') { 
       style = {top: '0', left: '0', 'transform-origin': 'top left'} 
      } else if (pos == 'tr') { 
       style = {top: '0', right: '0', 'transform-origin': 'top right'} 
      } else if (pos == 'bl') { 
       style = {bottom: '0', left: '0', 'transform-origin': 'bottom left'} 
      } else if (pos == 'br') { 
       style = {bottom: '0', right: '0', 'transform-origin': 'bottom right'} 
      }; 


      element.bind('click', function(e) { 
       e.stopPropagation(); 
       openMenu(); 
      }); 
      elClose.bind('click', function(e) { 
       e.stopPropagation(); 
       closeMenu(); 
      }); 
      $document.on('click', function() { 
       if (menuOpen == true) { 
        closeMenu(); 
       }; 
      }); 

      function openMenu() { 
       menuOpen = true; 
       elContent.removeClass('menu-hide'); 
       elContent.css(style); 
       setTimeout(function(){ 
        elContent.addClass('menu-open'); 
       }, 100); 
      }; 
      function closeMenu() { 
       menuOpen = false; 
       elContent.removeClass('menu-open'); 
       setTimeout(function(){ 
        elContent.addClass('menu-hide'); 
        elContent.removeAttr('style'); 
       }, 400); 
      }; 
     } 
    }; 
} 

因此,舉例來說,如果我使用一個主視圖菜單,假設頂部導航欄,然後在子視圖我還有其他的菜單控制一個選擇,當我點擊一個菜單時,它們都會打開。

我該如何解決這個問題?

+0

當我看到所有querySelectorAll,element.bind和removeClass(jQuery)代碼時,我停止查找解決方案。我認爲這是你的問題。你沒有做Angular。 –

+0

好的,但是然後..任何建議?我是新手。 – celsomtrindade

+0

好吧,它會變成一個長長的故事,但基本上你想用ng-class來處理添加和刪除模板中的類,單擊ng來處理點擊和子指令,這些指令通過要求它們而不是querySelector方法。很多人想學我猜;) –

回答

2

請求了關於如何要求父指令控制器的示例。這應該使你能夠使用更少的jQuery風格的代碼。

myModule.directive('myParentDirective', function(){ 
    return { 
     controller: function(){ 
      var vm = this; 
      vm.foo = 'bar'; 
     } 
    }; 
}); 

myModule.directive('myChildDirective', function(){ 
    return { 
     require: 'myParentDirective', 
     link: function(scope, elem, attrs, parentController){ 
      console.log(parentController.foo); // equals 'bar' 
     } 
    }; 
}); 

<my-parent-directive> 
    <my-child-directive></my-child-directive 
</my-parent-directive> 
+0

沒有必要做這個嵌套的指令,只要移動到一個ng-click/ng-class系統就可以了,而且代碼更好,更短。 ,但不知道如何把它放在一起,只有一件事......我不得不使用scope.apply來改變範圍值來驗證ng-class,這是一個好習慣嗎?因爲我讀過一些關於避免這種情況的文章。 – celsomtrindade

+0

Y ou應該避免使用$ scope。$ apply和$ scope。$ digest,但如果您在摘要循環之外執行操作,可能需要使用它。 –

+0

是的,我讀了一些關於它的內容,這也是爲什麼起初我試圖避免使用示波器。我的應用程序現在是一個非常複雜的應用程序,擁有大量數據,並且變得遲緩。有沒有辦法使用$應用於單個範圍值?我沒有發現任何關於它的事情。或者$ apply會運行$ digest? – celsomtrindade

1

你多次綁定到你的頁面上的多個元素:

// This will be an array of elements that will match the class .menu-button. 
// Not just the .menu-button element within your directive. 
// Try typing it in your browser developer tools console to see what I mean. 

angular.element(document.querySelectorAll(".menu-button")) 

如果你真的想抓住從指令中的各個元素,你需要找到他們喜歡這個:

// Use the element argument from the link function 
angular.element(element[0].querySelectorAll(".menu-button"));  

但是 - 在大多數情況下,它更容易(和更優雅)使用ng-clickng-class指令和等。只需在指令link函數中的scope對象上創建您的點擊處理程序,並將它們連接到html標記中。

scope.myClickHandler = function() { 
    // Magic goes here 
}; 

<div my-directive ng-click="myClickHandler"></div> 

希望這會有所幫助。