20

我正在使用 angularjs,我希望能够在需要时加载指令,而不是在页面开头加载所有指令。我正在尝试为我最常用的插件创建指令。

通过这种方式,一个直接可以yepnope在最终编译 html 之前加载所有需要的指令。

如果该指令与其他指令一起在页面开头加载,则一切正常。但是,如果稍后加载“子”指令(在“父”内),它不会生效。下面是“父”指令的编译字段中 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 加载指令。'child' 指令的部分代码如下:

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;
            });
        }
    }
});

首先我正在做的事情是可能的吗?

如果是这样,我做错了什么?

4

4 回答 4

17

如果要注册指令,在应用程序启动后,您将不得不使用 $compileProvider 而不是模块 API。例如...

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

然后,您可以在使用 $routeProvider 定义路由时使用“解析”功能,以使用脚本加载器加载惰性指令。为此,让函数返回一个承诺,一旦你的指令和其他惰性依赖项被加载,该承诺就会被解决。AngularJS 会在渲染路由之前等待 promise 被解析,从而确保你的指令在视图需要它之前准备好。我写了一篇博文,详细介绍了如何在 AngularJS 中实现延迟加载。它更详细地描述了我在这里所说的内容,可以在http://ify.io/lazy-loading-in-angularjs/找到

于 2013-04-21T10:45:29.533 回答
13

这就是我所做的,使用附加到应用程序的编译提供程序,使它可以从任何你有实际模块引用的地方访问。

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

然后稍后,在引导之后,您可以延迟加载一个被编译和链接的指令:

app.compileProvider.directive('SomeLazyDirective', function()
{
    返回 {
        限制:'A',
        模板网址:'模板/一些懒惰的指令.html'
    }
})
于 2014-02-05T11:14:10.367 回答
2

在搜索了这么久并没有得到任何答案之后,我最终得到了以下结果

  1. 创建一个角度应用程序。这也是一个角度模块。
  2. 您可以随时使用 app.directive(name,function) 向模块添加任何指令。这些可以是异步加载的指令。
  3. 您可以引导任何元素。引导时,将模块列表中的应用程序指定为 angular。

问题是 yepnope 没有像我需要的那样触发完整的功能。最后,我在 yepnope 之上构建了一个小包装器,似乎可以保证触发完整的函数。

最终代码如下所示:

var app3 = new Cai.AngApp('app3');
app3.loadControllers('app1.controller3', function () {
        app3.loadDirectives('jsonEditor', 'datePicker', function () {
            app3.bootstrap($('#d3'));
    });
});
于 2012-09-29T08:06:27.677 回答
-1

我不确定如何使用 angularJS 指令是一个合适的答案

我已经完成了以下操作,它完美无缺

  • 使用 mustache 列表来决定列表项模板。( https://github.com/janl/mustache.js/ )
  • 在加载您的应用程序 api 时,应仅加载 10 -50 条记录,具体取决于您的内容。
  • 在您即将到达结束时立即滚动列表,触发下一个 API 调用表单下一个 20 项,依此类推。
  • 如果您的数据没有变化,您可以将其存储在本地并重新填充。

  • 不断获取最新记录并在本地进行广告。

于 2018-01-19T02:19:47.687 回答