首页 > 解决方案 > require.js 使用来自不同模块的 AngularJS 指令

问题描述

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

我有一个 AngularJS 网络应用程序,其中有一个名为“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 的角度进行注入工作正常。当我创建 hero 编辑器模块并为其提供 dataListPane 模块依赖项时,Ng 也不会抛出异常(这意味着它知道该模块存在!)

我正在使用 ng 1.7.2

任何帮助将不胜感激。

标签: javascriptangularjsrequirejs

解决方案


app.js您还没有显示任何片段来表明您如何在更高级别(例如一些基本文件)将 RequireJS 模块组合在一起。但是,我怀疑您的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(...)
        };
    });

我在这里对这种方法进行了工作演示。

关于上述方法的两点:

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

推荐阅读