所以目前在我编写的Windows 8 WinJS应用程序中,我试图在app启动序列中加载xml文件,而启动画面仍在显示,因为这个xmldoc元素主页加载时需要加载,如果没有它,主页的加载将失败。
这是我在default.js中的启动序列:
exceptions.ValueError: Invalid XPath: meta[@name="DCSext.job_id"]@content

正如你可以看到我在哪里有#34; loadXML()"的注释行,这就是我需要loadXML()函数发生的地方。 这是我的loadXML()函数:
(function () {
"use strict";
var activation = Windows.ApplicationModel.Activation;
var app = WinJS.Application;
var nav = WinJS.Navigation;
var sched = WinJS.Utilities.Scheduler;
var ui = WinJS.UI;
app.addEventListener("activated", function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
// TODO: This application has been newly launched. Initialize
// your application here.
console.log("Newly Launched!");
var localSettings = Windows.Storage.ApplicationData.current.localSettings;
WinJS.Namespace.define("MyGlobals", { localSettings: localSettings });
// APP RUN TYPE CHECK AND SEQUENCE (FIRST RUN / NOT FIRST RUN):
if (MyGlobals.localSettings.values['firstRunCompleted']) {
console.log("NOT FIRST RUN!");
// CACHE VERSION CHECK. IF APP HAS BEEN UPDATED, INITIATE NEWLY ADDED CACHE VALUES HERE:
} else {
console.log("FIRST RUN!")
MyGlobals.localSettings.values['firstRunCompleted'] = true;
};
//loadXML(); have tried many things with this. doesn't work.
} else {
// TODO: This application has been reactivated from suspension.
// Restore application state here.
var currentVolume = app.sessionState.currentVolume;
if (currentVolume) {
console.log("RESTORE FROM SUSPENSION");
console.log(currentVolume);
};
}
nav.history = app.sessionState.history || {};
nav.history.current.initialPlaceholder = true;
// Optimize the load of the application and while the splash screen is shown, execute high priority scheduled work.
ui.disableAnimations();
var p = ui.processAll().then(function () {
return nav.navigate(nav.location || Application.navigator.home, nav.state);
}).then(function () {
return sched.requestDrain(sched.Priority.aboveNormal + 1);
}).then(function () {
ui.enableAnimations();
});
args.setPromise(p);
args.setPromise(WinJS.UI.processAll().then(function completed() {
loadSavedColour();
// Populate Settings pane and tie commands to Settings flyouts.
WinJS.Application.onsettings = function (e) {
e.detail.applicationcommands = {
"helpDiv": { href: "html/Help.html", title: WinJS.Resources.getString("settings_help").value },
"aboutDiv": { href: "html/About.html", title: WinJS.Resources.getString("settings_about").value },
"settingsDiv": { href: "html/Settings.html", title: WinJS.Resources.getString("settings_settings").value },
};
WinJS.UI.SettingsFlyout.populateSettings(e);
}

(loadXML是一个工作函数,适用于其他场景)
然而,问题是在loadXML函数完成之前,应用程序启动画面消失了,下一个home.html主页加载,启动附带的home.js,它有一个需要MyGlobals.xmlDoc的函数loadXML应该具有的对象。这会立即崩溃应用程序,因为MyGlobals.xmlDoc未定义/ null。 我以前通过在home.js中直接在home.html页面中运行loadXML来使这个应用程序工作,但是在那种情况下,每次导航到页面时都会重新加载XML文档,浪费时间和资源。因此,我试图将xmldocument加载到app启动/初始化中。 非常感谢!
答案 0 :(得分:1)
loadXML
具有异步功能,您需要处理它。
您不应期望loadFromFileAsync
(或任何其他异步函数)在返回调用者之前已完成。如果您的代码没有等待,您会发现MyGlobals.xmlDoc
值在您需要时无法设置。
我已将其重命名为更准确的行为。最大的变化是它返回一个Promise
,调用者可以使用它来正确等待加载Xml文档。此Promise
可以与其他Promise
一起使用,以便在您喜欢的情况下等待多个条件(或者在其他情况下,等待其他异步工作)。
function loadXMLAsync() {
return new WinJS.Promise(function (complete, error, progress) {
var localSettings = MyGlobals.localSettings.values;
var installedLocation = Windows.ApplicationModel.Package.current.installedLocation;
installedLocation.getFolderAsync("foldername").then(function (externalDtdFolder) {
externalDtdFolder.getFileAsync(values['currentBook']).done(function (file) {
Windows.Data.Xml.Dom.XmlDocument.loadFromFileAsync(file).then(function (doc) {
complete(doc);
});
});
});
});
};
然后,在使用中:
loadXmlAsync().then(function(doc) {
WinJS.Namespace.define("MyGlobals", {
xmlDoc: doc,
});
// and any other code that should wait until this has completed
});
上面的代码不能处理错误。
答案 1 :(得分:0)
我相信您需要做的是扩展启动画面,为您的应用提供更多时间来初始化UI。对于您的方案,它正在加载xml。
我建议你阅读How to extend the splash screen (HTML)。主要思想是在激活的事件中显示扩展的启动画面(您可以使用与默认图像相同的图像),然后调用loadXML。
答案 2 :(得分:0)
除了其他评论之外,您真正需要做的是将loadXml的承诺包含在您传递给args.setPromise的内容中。如您所知,setPromise是一种告诉应用程序加载程序在删除启动屏幕之前等待该承诺完成的方法。但是,在您的代码中,您多次调用setPromise。您应该做的是使用WinJS.Promise.join加入您关心的所有承诺(动画,loadXml和设置加载),这样您就可以获得一个承诺,然后等待所有其他三个承诺,以及何时 一个已完成,然后删除启动画面。
如果整个加载过程花费的时间太长,Alan建议使用扩展的启动画面是有帮助的,因为进行扩展启动可以让您完全控制正在发生的事情以及何时转换到主页面。