1

我有一個響應模板,我正在嘗試使用我的Angularjs應用程序。這也是我的第一個Angular應用程序,所以我知道我有很多錯誤並重新考慮了我的未來。AngularJS:在編譯和鏈接指令後,如何從指令內部運行JavaScript

我已經讀了足夠多關於角度的知識,我知道DOM操作被假設進入指令。

我有一個javascript對象負責模板重新大小的側面菜單和基本上外殼的模板。我將所有這些代碼移入一個指令並命名爲responsive-theme。

首先我添加了所有正在使用的方法,然後我在底部定義了App對象。我刪除了函數體來縮短代碼。

基本上,底部的對象是與所有方法一起使用的幫助對象。

var directive = angular.module('bac.directive-manager'); 

directive.directive('responsiveTheme', function() { 

return { 
    restrict: "A", 

    link: function($scope, element, attrs) { 


     // IE mode 
     var isRTL = false; 
     var isIE8 = false; 
     var isIE9 = false; 
     var isIE10 = false; 

     var sidebarWidth = 225; 
     var sidebarCollapsedWidth = 35; 

     var responsiveHandlers = []; 

     // theme layout color set 
     var layoutColorCodes = { 

     }; 

     // last popep popover 
     var lastPopedPopover; 

     var handleInit = function() { 
     }; 

     var handleDesktopTabletContents = function() { 
     }; 

     var handleSidebarState = function() { 
     }; 

     var runResponsiveHandlers = function() { 
     }; 

     var handleResponsive = function() { 
     }; 

     var handleResponsiveOnInit = function() { 
     }; 

     var handleResponsiveOnResize = function() { 
     }; 

     var handleSidebarAndContentHeight = function() {   
     }; 

     var handleSidebarMenu = function() { 
     }; 

     var _calculateFixedSidebarViewportHeight = function() { 
     }; 

     var handleFixedSidebar = function() { 
     }; 

     var handleFixedSidebarHoverable = function() { 
     }; 

     var handleSidebarToggler = function() { 
     }; 

     var handleHorizontalMenu = function() { 
     }; 

     var handleGoTop = function() { 
     }; 

     var handlePortletTools = function() { 
     }; 

     var handleUniform = function() { 
     }; 

     var handleAccordions = function() { 
     }; 

     var handleTabs = function() { 
     }; 

     var handleScrollers = function() { 
     }; 

     var handleTooltips = function() { 
     }; 

     var handleDropdowns = function() { 
     }; 

     var handleModal = function() { 
     }; 

     var handlePopovers = function() { 
     }; 

     var handleChoosenSelect = function() { 
     }; 

     var handleFancybox = function() { 
     }; 

     var handleTheme = function() { 
     }; 

     var handleFixInputPlaceholderForIE = function() { 
     }; 

     var handleFullScreenMode = function() { 
     }; 

     $scope.App = { 

      //main function to initiate template pages 
      init: function() { 

       //IMPORTANT!!!: Do not modify the core handlers call order. 

       //core handlers 
       handleInit(); 
       handleResponsiveOnResize(); // set and handle responsive  
       handleUniform();   
       handleScrollers(); // handles slim scrolling contents 
       handleResponsiveOnInit(); // handler responsive elements on page load 

       //layout handlers 
       handleFixedSidebar(); // handles fixed sidebar menu 
       handleFixedSidebarHoverable(); // handles fixed sidebar on hover effect 
       handleSidebarMenu(); // handles main menu 
       handleHorizontalMenu(); // handles horizontal menu 
       handleSidebarToggler(); // handles sidebar hide/show    
       handleFixInputPlaceholderForIE(); // fixes/enables html5 placeholder attribute for IE9, IE8 
       handleGoTop(); //handles scroll to top functionality in the footer 
       handleTheme(); // handles style customer tool 

       //ui component handlers 
       handlePortletTools(); // handles portlet action bar functionality(refresh, configure, toggle, remove) 
       handleDropdowns(); // handle dropdowns 
       handleTabs(); // handle tabs 
       handleTooltips(); // handle bootstrap tooltips 
       handlePopovers(); // handles bootstrap popovers 
       handleAccordions(); //handles accordions 
       handleChoosenSelect(); // handles bootstrap chosen dropdowns  
       handleModal(); 

       $scope.App.addResponsiveHandler(handleChoosenSelect); // reinitiate chosen dropdown on main content resize. disable this line if you don't really use chosen dropdowns. 
       handleFullScreenMode(); // handles full screen 
      }, 

      fixContentHeight: function() { 
       handleSidebarAndContentHeight(); 
      }, 

      setLastPopedPopover: function (el) { 
       lastPopedPopover = el; 
      }, 

      addResponsiveHandler: function (func) { 
       responsiveHandlers.push(func); 
      }, 

      // useful function to make equal height for contacts stand side by side 
      setEqualHeight: function (els) { 
       var tallestEl = 0; 
       els = jQuery(els); 
       els.each(function() { 
         var currentHeight = $(this).height(); 
         if (currentHeight > tallestEl) { 
          tallestColumn = currentHeight; 
         } 
        }); 
       els.height(tallestEl); 
      }, 

      // wrapper function to scroll to an element 
      scrollTo: function (el, offeset) { 
       pos = el ? el.offset().top : 0; 
       jQuery('html,body').animate({ 
         scrollTop: pos + (offeset ? offeset : 0) 
        }, 'slow'); 
      }, 

      scrollTop: function() { 
       App.scrollTo(); 
      }, 

      // wrapper function to block element(indicate loading) 
      blockUI: function (ele, centerY) { 
       var el = jQuery(ele); 
       el.block({ 
         message: '<img src="./assets/img/ajax-loading.gif" align="">', 
         centerY: centerY !== undefined ? centerY : true, 
         css: { 
          top: '10%', 
          border: 'none', 
          padding: '2px', 
          backgroundColor: 'none' 
         }, 
         overlayCSS: { 
          backgroundColor: '#000', 
          opacity: 0.05, 
          cursor: 'wait' 
         } 
        }); 
      }, 

      // wrapper function to un-block element(finish loading) 
      unblockUI: function (el) { 
       jQuery(el).unblock({ 
         onUnblock: function() { 
          jQuery(el).removeAttr("style"); 
         } 
        }); 
      }, 

      // initializes uniform elements 
      initUniform: function (els) { 

       if (els) { 
        jQuery(els).each(function() { 
          if ($(this).parents(".checker").size() === 0) { 
           $(this).show(); 
           $(this).uniform(); 
          } 
         }); 
       } else { 
        handleUniform(); 
       } 

      }, 

      updateUniform : function(els) { 
       $.uniform.update(els); 
      }, 

      // initializes choosen dropdowns 
      initChosenSelect: function (els) { 
       $(els).chosen({ 
         allow_single_deselect: true 
        }); 
      }, 

      initFancybox: function() { 
       handleFancybox(); 
      }, 

      getActualVal: function (ele) { 
       var el = jQuery(ele); 
       if (el.val() === el.attr("placeholder")) { 
        return ""; 
       } 

       return el.val(); 
      }, 

      getURLParameter: function (paramName) { 
       var searchString = window.location.search.substring(1), 
        i, val, params = searchString.split("&"); 

       for (i = 0; i < params.length; i++) { 
        val = params[i].split("="); 
        if (val[0] == paramName) { 
         return unescape(val[1]); 
        } 
       } 
       return null; 
      }, 

      // check for device touch support 
      isTouchDevice: function() { 
       try { 
        document.createEvent("TouchEvent"); 
        return true; 
       } catch (e) { 
        return false; 
       } 
      }, 

      isIE8: function() { 
       return isIE8; 
      }, 

      isRTL: function() { 
       return isRTL; 
      }, 

      getLayoutColorCode: function (name) { 
       if (layoutColorCodes[name]) { 
        return layoutColorCodes[name]; 
       } else { 
        return ''; 
       } 
      } 

     }; 

    } 

};   
}); 

本來App.init()對象的方法將在任何常規的HTML頁面的底部被調用,我有其他人做某些事情也將像Login.init特定頁面中使用()爲登錄頁面等等。

我看過那個計算器後 "Thinking in AngularJS" if I have a jQuery background?,意識到我想走回頭路的感覺,但我想用這個模板,我有,所以我需要適應復古這個解決方案。

我想在我的身體標記上使用此指令。

<body ui-view="dashboard-shell" responsive-theme> 
    <div class="page-container"> 
     <div class="page-sidebar nav-collapse collapse" ng-controller="SidemenuController"> 

      <sidemenu></sidemenu> 

     </div> 

     <div class="page-content" ui-view="dashboard"> 
     </div> 
    </div> 
</body> 

所以這是我的問題。這有點不類似的作品。我沒有得到任何控制檯錯誤,但是當我嘗試使用我的側邊菜單,它的javascript是它的指令,它不工作,直到我進入控制檯並輸入App.init()。之後,所有的模板JavaScript的作品。我想知道如何在這些指令中做響應主題的東西。我已經嘗試在編譯和鏈接部分使用它。我已經嘗試將代碼放在編譯和鏈接中,並在定義了所有內容之後從控制器調用$ scope.App.init()並在底部調用。我也試着把它放在jsfiddle中,但是如果沒有控制檯調用App.init(),就不能顯示真實的例子。

我的最終設計將有一些方法來通過UI路由器切換頁面,當路由切換時,它調用適當的方法或重新運行指令或其他東西。在每個頁面上運行的唯一方法是App.init()方法,其他所有內容都是頁面特定的。從技術上講,因爲這是一個單頁面應用程序,App.init()只需要爲應用程序運行一次。我將它綁定到ui-router中的父模板,並且將切換的頁面都使用此shell模板。有一些對象需要訪問其他對象來調用他們的方法。

對不起,可能是一個令人困惑的職位。我現在正在努力嘗試將角色視角中的某些方法放在一起。我會繼續編輯帖子,因爲我會收到回覆以提供更多示例。

回答

5

你說I have read enough about angular that I know DOM manipulations are suppose to go inside a directive但它聽起來像你錯過了一個指令的要點。指令應該處理DOM操作,是的,但不是整個頁面的一個指令。頁面的每個元素(或段)都應該有自己的指令(假設需要在該元素上完成DOM操作),然後應該處理這些元素與數據(或模型)之間的交互。

你已經創建了一個巨大的指令,並試圖讓它做太多。幸運的是,你有點兒用一種方式設計你的代碼,以至於把它分解成幾個指令不應該太難。基本上,你的每一個handle函數應該是它自己的指令。

所以你會碰到這樣的:

.directive('sidebarMenu', function(){ 
    return { 
     template: 'path/to/sidebar/partial.html', 
     link: function(scope, elem, attrs){ 
      // insert the code for your 'handleSidebarMenu()' function here 
     } 
    }; 
}) 
.directive('horizontalMenu', function(){ 
    return { 
     template: 'path/to/horizontal/partial.html', 
     link: function(scope, elem, attrs){ 
      // insert the code for your 'handleHorizontalMenu()' function here 
     } 
    }; 
}) 

,然後你的觀點看起來是這樣的:

<body ui-view="dashboard-shell" responsive-theme> 
    <div class="page-container"> 
     <div class="page-sidebar nav-collapse collapse"> 

      <horizontal-menu></horizontal-menu> 

      <sidebar-menu></sidebar-menu> 

     </div> 

     <div class="page-content" ui-view="dashboard"> 
     </div> 
    </div> 
</body> 

然後你不需要SidebarmenuController因爲你的控制器功能不該」不會像邊欄那樣處理DOM元素。控制器應該只處理要在視圖中顯示的數據,然後該視圖(或.html文件)將通過使用您編寫的指令來處理數據的顯示和操作。

這有道理嗎?試着將這個巨大的指令分解成許多處理DOM中特定元素或特定任務的較小指令。附件號碼:

+0

PS。我強烈建議你從角度來看「開發者指南」,尤其是[在這裏]找到的Directives部分(http://code.angularjs.org/1.2.0-rc.3/docs/guide/directive ) – tennisgent

+0

我知道這個指令是巨大的,沒有遵循最佳實踐,除了沒有花時間更多地分解它之外,我沒有錯過任何一點。但是我有那個在模板的不同時間調用多個方法的幫助器對象。如果我更多地指出這個指令,我將如何調用一些分組方法。這是我不明白的主要問題。我同意他們中的一些可以並應該放在單獨的指令中,並且最終會發生,一旦我能夠制定如何分開指令並在App對象上調用組方法。 – lumberjacked

+0

如果您有指令需要溝通,您可以將共享對象傳遞給所有人。

。您可以使用該共享對象來設置通用值並註冊交叉指令功能 –