2014-11-20 12 views
1

我有一個指令創建如下:

elements.directive('myApp', function(){ 
return { 
    restrict: 'E', 
    templateUrl: "/path/to/myapp.html", 
    controller: function($scope, $timeout) { 
      // loads the script when the dom has finished rendering 
     var loadScript = function() { 
      var script = document.getElementById('myappjs'); 
      if(script){ 
       /* 
       * the script is already appended but needs to be re-executed 
       * - remove and re-append the script element? 
       * - $route.reload() in order to refresh the page? 
       * - other solutions 
       */ 
      } else { 
       // the script has never been loaded before and the script element is created from scratch 
       var s = document.createElement('script'); 
       s.id = "myappjs"; 
       s.src = '/path/to/require.js'; 
       s.setAttribute('data-main', '/path/to/script'); //.js needs to be omitted 

       document.body.appendChild(s); 
      } 
     }; 
     // when the DOM has finished rendering, loadScript is executed: 
     $timeout(loadScript, 0); 
    } 
}; 
}); 

「我的應用程序內」元素是NG-內的推杆開關容器。基本上它會加載一個svg和腳本來執行它。 問題是,腳本只在ng-switch第一次匹配'my-app'元素時執行:如果我從另一個指令(總是在ng-switch容器內)切換到「my-app」,它就可以工作。 但是,如果我再次移動到另一個指令,然後再次移動到「我的應用程序」,腳本不再工作。

我試圖使用$ route.reload(),當它發現腳本之前已經被追加,但它會導致無限循環。 然後我嘗試從DOM中刪除腳本元素並重新附加它,但腳本無論如何都不加載。

因此,svg的內容僅在第一次加載頁面時加載。 有沒有人有任何建議?

+0

爲什麼不將任何值傳遞給作用域並操縱指令中的數據? – 2014-11-20 19:51:26

+0

最後,我通過在運行函數中包裝外部JS的所有代碼來解決問題。第一次在外部文件本身內執行。然後,每當ng-switch匹配指令時,它都會在指令內執行。 – user2861867 2014-11-21 11:08:41

+0

感謝分享! – 2014-11-21 13:19:57

回答

0

我解決了纏繞運行函數中的外部JS的全部代碼:

/* app.js file */ 

var myAppRun = function() { 
    /* the code of my app */ 
} 
myAppRun(); 

的HTML開關:

<!-- select-page-template.html file --> 
<div ng-switch on="selectedPage"> 
    <my-app ng-switch-default></my-app>  
    <another-directive ng-switch-when="another_directive"></another-directive> 
</div> 

和指令定義:

/* directives.js file*/ 
elements.directive('myApp', function(){ 
    return { 
     restrict: 'E', 
     templateUrl: "/path/to/myapp.html", 
     controller: function($scope, $timeout) { 
      var loadScript = function() { 
       if(typeof myAppRun === "function"){ 
       myAppRun(); 
       return; 
      } 

       var s = document.createElement('script'); 
        s.src = '/path/to/myapp.js'; 
       document.body.appendChild(s); 
      }; 

       $timeout(loadScript, 0); 
     } 
    }; 
}); 

如果myAppRun函數尚未定義,則腳本將被創建並附加到HTML主體。 myAppRun()將在myapp.js文件中自動執行。 否則每當ng-switch匹配默認條件時,myAppRun()將在指令控制器內被調用。

'loadScript'僅在使用$ timeout呈現DOM後執行。通過這種方式,myapp.js可以找到需要處理的所有元素(例如myapp模板中的一個SVG元素),而不會拋出「找不到元素」錯誤。