这取决于您认为的进步。 Durandal 在后台使用 require.js 来动态加载 javascript 文件,因此当您第一次启动项目并加载 main.js 时,require 正在执行查找所有请求的 js 文件并加载它们的工作。如果你想展示它的进展可能会很棘手。这是一个关于利用 requirejs 加载过程的 google 小组讨论的链接:
https://groups.google.com/forum/#!topic/requirejs/JX-9bHP1BBo
这种方法只有在您不使用网站的编译版本时才有用。在durandal docs 页面上,有一整节内容是关于通过将所有 js 和 html 视图组合到一个文件中来优化您的项目,该文件在启动时加载,并且完全不需要显示文件加载进度。
如果您在向用户展示您的项目之前必须完成一些长时间运行的进程,您可以在 shell 模块的激活功能中执行此操作。我已经使用嵌套的jquery promise objects 和blockUI plugin 完成了这项工作。您需要做的是从您的 activate 函数返回一个承诺,这将导致 durandal 等到您完成启动代码后再加载您的 shell ui。在该承诺中,您使用jquery's when/then 函数来调用任何数量的其他函数,这些函数也必须返回承诺。对于每个被调用的函数,作为参数传入一个函数来更新你的进度 ui。这是我的 shell 激活函数的示例
function activate() {
var def = new $.Deferred();
try {
var messageBoxHtml = [
'<div class="messageBox">',
'<div class="modal-header">',
'<h3>Processing</h3>',
'</div>',
'<div class="modal-body">',
'<p class="message" id="blockMessageTag">Processing request, please wait...</p>',
'<div class="progress progress-striped active page-progress-bar">',
'<div id="blockMessageTagProgress" class="progress-bar progress-bar-warning" style="width: 0%;"></div>',
'</div>',
'</div>',
'<div class="modal-footer">',
'</div>',
'</div>'
].join('\n');
$.blockUI({ message: messageBoxHtml });
var updateMain = function (msg) {
def.notify(msg);
};
var totalProgress = 0;
def.progress(function (newMessage) {
logger.log("Boot Progress", "shell", newMessage);
$("#blockMessageTag").text(newMessage + "...");
totalProgress++;
$("#blockMessageTagProgress").width((totalProgress * 25) + '%');
});
$.when(module1.dowork(updateMain), module2.dowork(updateMain))
.done(function () {
$.unblockUI();
router.map([
{ route: 'Home', moduleId: 'views/myhome', title: 'Home' },
]).mapUnknownRoutes('views/Common/404', 'not-found')
.activate().done(function () {
def.resolve();
}).fail(function (xh, status, msg) {
logger.log(msg, "Shell Startup Failure", xh);
$("#blockMessageTag").text("Failure: Check Console Log For Details - 1");
$("#blockMessageTagProgress").width('0%');
def.fail();
});
}).fail(function (xh, status, msg) {
logger.log(msg, "Shell Startup Failure", xh);
$("#blockMessageTag").text("Failure: Check Console Log For Details - 2");
$("#blockMessageTagProgress").width('0%');
def.fail();
});
}
catch (ex) {
logger.log(ex.message, "Shell Startup Failure", ex);
$("#blockMessageTag").text("Failure: Check Console Log For Details - 3");
$("#blockMessageTagProgress").width('0%');
def.fail();
}
return def.promise();
}
所有的 module1.dowork 函数也必须像这样返回一个 promise:
function (uiMsgBox) {
var def = new $.Deferred();
uiMsgBox('Starting Process');
try {
//do whatever work you need to do here
uiMsgBox('Process Complete');
def.resolve(jsret);
} catch (error) {
def.reject();
}
return def.promise();
};
您传递给长期运行的函数(module1.dowork 和 module2.dowork)的对 updateMain 函数的每次调用都会根据您返回给 durandal 的承诺调用 notify。通知将导致调用进度函数并更新您的进度 UI。我有点作弊,只是硬编码了进度条间隔。条形图从 0% 宽度开始,每次调用都会发生变化,方法是将 totalProgress 值增加 1 并将其乘以预期调用次数的正确百分比。每个 dowork 方法都应该调用更新进度 ui 两次,因此总共调用 4 次,这使得 progess 增量为 25,(100 / 4)。您需要根据需要进行调整。