require.js从不同的模块中使用AngularJS指令

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了require.js从不同的模块中使用AngularJS指令相关的知识,希望对你有一定的参考价值。

当由不同的模块调用时,模块中的指令不会被引导

我有一个AngularJS Web应用程序,其中包含一个名为“heroEditor”的模块:

// 3) heroEditor ng module is created and injects the dataListPane
// module as a dependency (see step 1)
define('heroEditor/module',['common/module', 'dataListPane/module'], function(){
    return angular.module('heroEditor', ['common', 'dataListPane']);
});

正如您在上面所看到的,它依赖于另一个名为'dataListPane'的ng模块:

// 1) define the dataListPane ng module
define('dataListPane/module',[], function(){
    return angular.module('dataListPane', []);
});

这一切都通过requirejs连线,所有内容都按正确的顺序调用。在模块'heroEditor'中我有一个指令,也称为'heroEditor':

// 4) Register the heroEditor directive on the heroEditor module
// this directive will try to consume a dataListPane directive instance
// which should be available as it was registered (see step 2)
define('heroEditor/directive/heroEditor',['heroEditor/module', 'heroEditor/service/heroData'], function(heroEditorMod){
    heroEditorMod.directive('heroEditor', ['heroData', function(heroData){
        //hero editor directive definition
    });
});

在依赖项中,'dataListPane'模块是我想在'heroEditor'指令的标记中使用的指令。这是'dataListPane'指令:

// 2) Register the dataListPane directive on the dataListPane module
define('dataListPane/directive/dataListPane',['dataListPane/module'], function(dataListPaneMod){
    dataListPaneMod.directive('dataListPane', function(){
        // [NEVER CALLED] data list pane directive content
        return {scope:{},templateUrl:'a/valid/path/to/dataListPane.html'};
    });
});

在英雄编辑器的标记中,我尝试放入数据列表窗格指令的实例(它应该可用!),就像这样

<data-list-pane></data-list-pane>

在浏览器中,尽管我将其包含在我的标记中,但数据列表窗格的指令功能永远不会触发。从requirejs的角度来看,注入工作正常。当我创建英雄编辑器模块并给它dataListPane模块依赖项时,Ng也不会抛出异常(这意味着它知道模块存在!)

我正在使用1.7.2

任何援助都将受到极大的赞赏。

答案

您没有显示任何片段,表明您是如何将RequireJS模块放在更高的级别(例如某些基础app.js文件)。但是,我怀疑你的dataListPane/directive/dataListPane模块永远不会是任何RequireJS依赖关系定义的一部分(即从app.js无法访问),这就是为什么里面的代码永远不会执行。

确保AngularJS样式模块声明的一种方法是让AngularJS模块本身确保执行此类声明的代码。

// dataListPane/module.js
define(
    'dataListPane/module',
    ['dataListPane/directive/dataListPane'],
    function (dataListPane) {
        var mod = angular.module('dataListPane', []);
        return function () {
            dataListPane.init(mod);
            return mod;
        };
    });

// dataListPane/directive/dataListPane.js
define(
    'dataListPane/directive/dataListPane',
    // You cannot depend on 'dataListPane/module' here! (i.e. cyclic dependency)
    ['exports'],
    function (exports) {
        exports.init = function (mod) {
            // mod.directive(...)
        };
    });

I've made a working demonstration of this approach here.

关于上述方法的两点:

  1. 分离的指令定义(即你的情况下是dataListPane)不能明确依赖于它需要声明的AngularJS模块,否则它是一个循环依赖
  2. 请注意,AngularJS模块显式依赖于指令定义所在的RequireJS模块并对其进行初始化

以上是关于require.js从不同的模块中使用AngularJS指令的主要内容,如果未能解决你的问题,请参考以下文章

require js

JavaScript模块化-require.js,r.js和打包发布

Require.js与Sea.js的区别

JavaScript中模块化工具require.js

require.js 源码解读——配置默认上下文

JS模块化编程--require应用