在阅读有关激活剂的文档后,我仍然对如何使用激活剂感到困惑。我想做的很简单:
我已经定义了一个名为global的requireJS模块。当我在其他模块中使用此模块时,不会调用它的激活功能。我需要它。
如果我使用compose:加载模块,激活函数就可以了。但是,如果我只是将它作为AMD模块加载,他们就不会。这就是我想解决的问题。
注意:我的模块是一个单独的,我只需要激活才能实际运行一次,所以我尝试了类似这样的东西,它不起作用,我的shell.js
define(['plugins/router', 'durandal/app', 'plugins/ajax','durandal/global'], function (router, app,ajax,global) {
var vm = {};
vm.global = global;
vm.activate= function () {
return vm.rebuildRouter();
//not sure what this does, does it return a promise, does it run global's activate, does it hook up global so it activates at a later time, and if so when?
global.activator.activateItem(global); //I created an activator and called in activator inside global. Since its a singlton I think I only need one?
//Since I wasn't sure how to use activators I had to do this instead:
var promise = global.activate();
return promise;
//which works only the first time
}
如果有人可以向我解释这个激活业务,我会很感激。我一直使用激活compose,并且按照我想要的方式工作。我只是不明白我需要做些什么才能让它按上述方式工作,并且无法找到一个简单的例子来说明如何让任何js模块以相同的方式运行。
答案 0 :(得分:3)
activator是一个特殊的计算的obseravble ,当其值尝试更改时,其写入函数会强制执行activation lifecycle。
canDeactivate
在当前值canActivate
deactivate
在当前值activate
醇>
使用激活器强制某些对象在其值发生变化时触发这些事件,并在canDeactivate
或canActivate
返回false
时阻止更改。
听起来你不想要一个激活剂。您没有尝试根据这些规则强制执行值更改,您正在尝试确保模块在使用之前执行某些逻辑。它只需要执行一次这个逻辑,因为它是一个单例。
不幸的是,RequireJS没有提供等待模块执行异步工作的方法(我知道)。
这是你可以做的一件事。由于Durandal的app.start
初始化是一个异步过程,您可以将其挂钩,以便在setRoot
初始化之后调用global
。
define(['durandal/app', 'plugins/ajax', 'durandal/global'], function (app,ajax) {
return function GlobalModule() {
activate: function() {
return //some promise;
}
};
});
define(['durandal/system', 'durandal/app', 'durandal/global'],
function (system, app, global) {
app.configurePlugins({ /* plugins */ });
app.title = 'App';
app.start()
.then(global.activate)
.then(function () {
app.setRoot('shell');
});
});
这将确保setRoot
在global
完成激活之前不会启动。然后,在您的任何应用代码中使用它都应该是安全的。
请记住,我不知道durandal/global
是什么,这项工作取决于activate
是一个承诺返回功能。
答案 1 :(得分:2)
你的问题中有许多不正确的假设...你正在混淆AMD模块解析(由require.js完成)和视图合成(一个durandal概念),好像它们是相同的东西。
无论如何,我认为你在这里与激活者走错了路(因为它们与简单的AMD模块分辨率是一个单独的概念)所以我要回避实际问题,并回答我认为你的问题应该是,如何将自动初始化逻辑添加到AMD模块?
鉴于您只希望初始化发生一次,那就告诉我您还希望模块是单例。
无论哪种方式,我都认为实现初始化逻辑没有比模块的构造函数更精细的地方。
基本上你想要将AMD模块作为构造函数实现,将你的init逻辑放在那里,并利用单例模式,这样初始化逻辑只发生一次。
这对您来说可能是一个有用的资源:
http://unscriptable.com/2011/09/22/amd-module-patterns-singleton/
如果我错过了你在这里尝试做的事情,请道歉。
答案 2 :(得分:0)
我最终完成了我所需要的,但这是最好的方式和/或如何做到这一点?我认为这不是理想的,因为我需要在每个模块中使用所有这些代码,包括我所包含的每个模块:
var viewModel = {}; viewModel.global = activator.create();
viewModel.activate = function () {
return $.when(viewModel.global.activateItem(global),
... other ajax calls and stuff
))
.then(function () {
//stuff I used to have in my activate function before, that needs global to already exist
});
};
这真的是如何正确使用激活剂吗?我上面的工作,但正如有人指出我可以调用global.activate()而不是activateItem(全局),我根本不需要激活器..那么,目的是什么它?
当你撰写某些东西时,激活生命周期就会自行发生。我正在尝试构建一个具有生命周期的模块,即使我没有编写它,这可能吗?