2012-09-21 46 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个项目等。
  • 如果您的数据没有变化,您可以将其存储在本地并重新填充。

  • 保持获取最新的记录和广告在本地。使用引导对孩子