2012-09-21 77 views
18

我正在使用angularjs,我希望能夠在需要時加載指令,而不是在頁面開始時加載所有指令。我試圖爲我最常用的插件創建指令。如何在angularjs中加載指令?

這樣,一個direct可以在最終編譯html之前使用yepnope加載所有需要的指令。

如果指令在頁面開始時與其他指令加載,則一切正常。但是,如果'孩子'指令稍後加載(在'父'內),它不會生效。以下是'parent'指令編譯字段中pre字段的代碼。

... 
    var pre = function (scope, element, attrs) { 
     element.html('Please wait. Loading...'); 
     ang.loadDirectives('caiDatePicker', function() { 
      console.log('loaded'); 
      scope.data.raw = scope.rawData; 
      var html = createObjUi(scope, scope.data, scope.defn); 
      element.html(html); //data 
      $compile(element.contents())(scope.$new()); 
      scope.$apply(); 
     }); 
    }; 
    return { restrict:'A', compile: {pre:pre,post:function(){...}}; 

ang.loadDirectives使用yepnope加載指令。 「兒童」指令的部分代碼如下:

angular.module('mycomponents') //PS: I'm assuming this will fetch the already created module in the 'parent' directive 
.directive('caiDatePicker', function ($parse) { 
    return { 
     scope: {}, 
     restrict: 'A', 
     link: function (scope, element, attrs) { 
      scope.$watch('this.$parent.editing', function (v) { 
       scope.editing = v; 
      }); 
      yepnope({ 
       test: $().datePicker, 
       nope: [ 
        '/content/plugins/datepicker/datepicker.js', //todo: use the loader 
        '/content/plugins/datepicker/datepicker.css' 
       ], 
       complete: function() { 
        if (scope.model && scope.model.value) { 
         var date = scope.model.value; 
         element.val(date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear()); 
        } 
        element.datepicker({ weekStart: 1, format: 'dd/mm/yyyy' }) 
         .on('changeDate', function (ev) { 
          scope.model.value = ev.date; 
          scope.$apply(); 
         }); 
       } 
      }); 
      attrs.$observe('path', function (v) { 
       var fn = $parse(v); 
       var model = fn(scope.$parent); 
       scope.model = model; 
      }); 
     } 
    } 
}); 

我是在做什麼,甚至可能在第一個地方?

如果是這樣,我做錯了什麼?

回答

2

尋找這麼久,沒有得到任何答覆後,我結束了以下

  1. 創建角度應用。這也是一個角度模塊。
  2. 您可以隨時使用app.directive(name,function)向模塊添加任何指令。這些可以是異步加載的指令。
  3. 您可以引導任何元素。引導時,將模塊列表中的應用程序指定爲角度。

問題是,yepnope沒有激發完整的功能,因爲我需要他們。最後,我在yepnope之上構建了一個小包裝器,它看起來能夠保證完整的函數被激發。

最終代碼看起來像:

var app3 = new Cai.AngApp('app3'); 
app3.loadControllers('app1.controller3', function() { 
     app3.loadDirectives('jsonEditor', 'datePicker', function() { 
      app3.bootstrap($('#d3')); 
    }); 
}); 
+0

有趣的方法。但這意味着,多個引導程序。它會起作用嗎?另外,你能解釋一下你在ang.loadDirectives中做了什麼嗎? – Lior

+0

解決您的yepnope問題,您可以按照此評論的第一個例子:https://github.com/SlexAxton/yepnope.js/issues/91#issuecomment-14526165 – heralight

17

如果你想註冊的指令,該申請已自舉後,你將不得不使用$ compileProvider代替模塊的API。例如...

$compileProvider.directive('SomeLazyDirective', function() 
{ 
    return { 
     restrict: 'A', 
     templateUrl: 'templates/some-lazy-directive.html' 
    } 
}) 

然後你就可以定義路由時與$ routeProvider加載使用腳本裝載機懶指令中使用「解析」功能。要做到這一點,讓函數返回一旦您的指令和其他懶惰依賴已經加載就解決的承諾。 AngularJS會在呈現路由之前等待承諾解決,從而確保您的指令在視圖需要之前就緒。我寫了一篇博客文章,詳細介紹如何在AngularJS中實現延遲加載。它更詳細地描述了我在這裏所陳述的內容,它可以在http://ify.io/lazy-loading-in-angularjs/

11

這裏是我所做的,使用連接到應用程序的編譯提供程序,使它可以在任何有實際模塊引用的地方訪問。

 
var app = angular.module('app'); 
app.config(function ($compileProvider) { 
    app.compileProvider = $compileProvider; 
}); 

再後來就,引導你可以懶洋洋地加載的被編譯和連接指令後:

 
app.compileProvider.directive('SomeLazyDirective', function() 
{ 
    return { 
     restrict: 'A', 
     templateUrl: 'templates/some-lazy-directive.html' 
    } 
}) 
+1

這個工作對我來說,一個有用的帖子也是在這裏:HTTP ://www.codeproject.com/Articles/838402/Lazy-loading-directives-in-AngularJS-the-easy-way –

0

我不知道如何使用angularJS指令將是一個合適的答案

我做了以下工作,它的工作完美無缺

  • 使用小鬍子列表來決定列表項模板。(https://github.com/janl/mustache.js/
  • 在您的應用程序加載時,apis應只加載10-50個記錄,具體取決於您的內容。
  • 一旦您即將結束,列表中的滾動,然後下一個apis呼叫表格下一個20個項目等。
  • 如果您的數據沒有變化,您可以將其存儲在本地並重新填充。

  • 保持獲取最新的記錄和廣告在本地。使用引導對孩子