如何查找dojo模块的模块ID

时间:2014-02-24 17:30:33

标签: dojo amd

我有一组全局javascript页面资源需要从许多不同的dojo类进行管理。在旧版本(dojo 1.6)中,我使用类实例的declaredClass属性来确定哪个类注意访问共享资源并采取适当的行动。

现在我正在使用AMD加载程序并且已经适当地转换了我的模块,这种技术不再适用。事实上,似乎没有办法在运行时找出类实例的模块ID。我查看了dojo 1.9 dojo\_base\declare代码,但是当通过c3mro函数存在公共基类时,似乎只分配了

以下是declaredClass函数与旧版dojo相比看似反直觉的两个例子。

案例1:具有共享基类的两个类

Base.js

define(["dojo/_base/declare"], function (declare) {
    return declare(null, {        
    });
});

ClassA.js ClassB.js

define(["dojo/_base/declare", "./_Base"], function(declare, _Base) {
    return declare([_Base], {
    });
});

测试脚本

require(["myapp/test/ClassA", "myapp/test/ClassB"], function (A, B) {
    var a = new A();
    var b = new B();

    console.log(a.declaredClass);
    console.log(b.declaredClass);
});

输出

uniqName_1
uniqName_1

如果我更改了测试,那么ClassAClassB不会从_Base继承,或者通过将_Base作为单个参数传入来使用简单继承,而是比在数组中,我得到undefined输出。

ClassA.js ClassB.js

define(["dojo/_base/declare", "./_Base"], function(declare, _Base) {
    return declare(null, {
    });
});

define(["dojo/_base/declare", "./_Base"], function(declare, _Base) {
    return declare(_Base, {
    });
});

测试输出

undefined
undefined

我可以通过显式设置className函数的declare()参数来解决这个问题,但显然不鼓励编写可移植模块。

那么,有没有办法从类实例中知道用什么模块ID来实例化那个类?

更新

我试图支持的用例是_Base类来调解对某些全局资源的访问。这是1.7之前的逻辑正在做的骨架。显然,我可以创建一种识别资源用户的不同方法,但我很好奇是否有办法使1.7之前的行为适应AMD基础设施。

Base.js

define(["dojo/_base/declare", "dojo/_base/kernel"], function (declare, kernel) {
    return declare(null, {
        activate: function(item) {
            // Get the set of current active items
            var activeItems = kernel.global.activeItems || {};

            // Disable anything that is currently active, unless it's for the
            // current instance
            for (var key in activeItems) {
                if (key !== this.declaredClass) {
                    activeItems[key].deactivate();
                }
            }

            // Activate and save the current item
            item.activate();
            activeItems[this.declaredClass] = item;

            kernel.global.activeItems = activeItems;
        },

        deactivate: function(item) {
            var activeItems = kernel.global.activeItems || {};
            if (activeItems[this.declaredClass]) {
                item.deactivate();
                delete activeItems[this.declaredClass];
            }
        }      
    });
});

1 个答案:

答案 0 :(得分:0)

实际上,唯一可行的方法是使用declare()参数。我不知道你想要实现什么,但我认为这是一个很好的方法。如果重命名模块,则使用declaredClass的代码仍然有效。

此外,Dojo允许您自定义包并选择应使用的包名称以及该包的路径。这意味着您可以同时拥有myPackage/ClassA,但您也可以命名包,以便获得myExtremelyCoolPackage/ClassA。如果你没有静态类名,那么使用该类名的代码实际上会破坏。

除此之外,AMD中几乎不需要类名,您不需要它们来加载模块或声明性标记。他们在那里的唯一原因是支持仍然依赖于类名的遗留代码。因此,如果您真的不想将它放在declare()中,那么说出您想要使用它的用例可能会有用。