我不确定这个问题的正确标题/标题应该是什么。我是WinJS的新手,来自.NET网络表单和winclient背景。
这是我的场景。我有一个导航WinJS应用程序。我的结构是:
- default.html
- (导航控制器)
- (设置弹出按钮)
- pages/Home.html
- pages/Page2.html
因此,在default.js文件的顶部,它设置了以下变量:
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var nav = WinJS.Navigation;
我似乎无法在设置弹出按钮或任何页面中的任何位置使用这些变量:就绪函数。它们的作用域仅限于default.js?
同样,在interwebs(链接)上是否有资源显示如何在我的每个"页面"之间正确共享变量、事件和数据?
我立即需要克服的场景是设置。在我的设置弹出按钮中,我读取并允许用户选择性地设置以下应用程序设置:
var applicationData = Windows.Storage.ApplicationData.current;
var localSettings = applicationData.localSettings;
localSettings.values["appLocation"] = {string set by the user};
我想在我的default.js文件中,甚至在我的一个导航页面中响应该事件,但我不知道在哪里"侦听"。我的直觉是倾听隐藏事件,但我如何将其范围扩大到我想要倾听的页面?
Bryan。这里是codefoster。如果你移动你提到的线。。。
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var nav = WinJS.Navigation;
在immediate函数之外,它们将在全局范围中,并且您可以在任何地方访问它们。这是我在应用程序中做的第一件事。你会听到关于使用全局作用域的警告,但人们试图避免的是在全局作用域中丢弃所有的模式。只要你能控制你在里面放的东西,你就没事。
所以把它们放在default.js…上立即函数的开头
//stuff here is scoped globally
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var nav = WinJS.Navigation;
(function () {
//stuff here is scoped to this file only
})();
如果你正在保存一些数据,并且只需要将其保存在内存中,你可以将其挂在应用程序变量上,而不是将其保存到本地存储中。这将使其可用于整个应用程序。
//on Page2.js
app.myCustomVariable = "some value";
//on Page3.js
if(app.myCustomVariable == "some value") ...
关于您的迫切需求:
- 正如在另一个答案中提到的,您可以使用
datachanged
事件
关注共享变量:
- 如果有一些变量希望对应用程序保持全局性,则可以将它们放置在Jeremy答案中提到的匿名函数之外。通常,这是在default.js中完成的。需要确保使用全局变量的脚本位于定义全局变量的剧本之后-在
default.html
中。通常,这样的变量将指向singleton类。例如:我在我的一个应用程序中使用它来存储应用程序后端服务的authclient/serviceclient。这样,多个页面的视图模型就不需要创建对象的实例,也不需要在WinJS命名空间下引用它 -
WinJS还有Namespace的概念,它允许您组织函数和类。示例:
WinJS.Namespace.define('Utils.Http', { stringifyParameters: function stringifyParameters(parameters) { var result = ''; for (var parameterName in parameters) { result += encodeURIComponent(parameterName) + '=' + encodeURIComponent(parameters[parameterName]) + '&'; } if (result.length > 0) { result = result.substr(0, result.length - 1); } return result; }, }
-
当使用WinJS.Navigation.Navigation导航到页面时,第二个参数
initialState
可用作该页面的就绪事件处理程序的options
参数。这将是向页面传递arguments
的推荐方式,除非这是应用程序数据或会话状态。应用程序数据/会话状态需要单独处理,并且需要单独讨论。应用程序导航历史记录由winjs库持久化;它确保了如果应用程序在暂停后再次启动-导航时选项将再次传递到页面。最好将options
对象中的属性保持为简单的基元类型。
问候事件:
- 通常,应用程序使用winjs库中的事件。这可以通过使用
addEventListener
注册事件处理程序或在元素上设置onclick
等事件属性来实现。事件处理程序通常在页面的ready
事件处理程序中注册 -
如果您正在编写自己的自定义控件,或者有时在视图模型中,则可能需要公开自定义事件。Winjs.UI.DOMEventMixin、Winjs.Utilities.createEventProperties可以使用Winjs.class.mix与您的类混合。示例:
WinJS.Class.mix(MyViewModel, WinJS.Utilities.createEventProperties('customEvent'), WinJS.UI.DOMEventMixin);
-
最常用的是绑定,以使视图模型可观察。有关详细信息,请参阅相应的示例和api文档。示例:
WinJS.Class.mix(MyViewModel, WinJS.Binding.mixin, WinJS.Binding.expandProperties({ items: '' }));
以下是我最终所做的,这是所有答案的组合:
-
创建了ViewModel.Settings.js文件:
(function () { "use strict"; WinJS.Namespace.define("ViewModel", { Setting: WinJS.Binding.as({ Name: '', Value: '' }), SettingsList: new WinJS.Binding.List(), }); })();
-
将该文件添加到我的default.html(导航容器页面)
<script src="/js/VMs/ViewModel.Settings.js"></script>
-
添加以下内容以设置默认值并开始"侦听"更改
//add some fake settings (defaults on app load) ViewModel.SettingsList.push({ Name: "favorite-color", Value: "red" }); // listen for events var vm = ViewModel.SettingsList; vm.oniteminserted = function (e) { console.log("item added"); } vm.onitemmutated = function (e) { console.log("item mutated"); } vm.onitemchanged = function (e) { console.log("item changed"); } vm.onitemremoved = function (e) { console.log("item removed"); }
然后,在我的应用程序(页面)或设置页面中,我可以触发设置事件:
// thie fires the oniteminserted
ViewModel.SettingsList.push({
Name: "favorite-sport",
Value: "Baseball"
});
// this fires the itemmutated event
ViewModel.SettingsList.getAt(0).Value = "yellow";
ViewModel.SettingsList.notifyMutated(0);
// this fires the itemchanged event
ViewModel.SettingsList.setAt(0, {
Name: "favorite-color",
Value: "blue"
});
// this fires the itemremoved event
ViewModel.SettingsList.pop(); // removes the last item
当您更改需要实时更新的数据时,请调用applicationData.signalDataChanged()
。然后,在关心获取更改通知的地方,监听applicationData对象上的datachanged
。这也是在计算机之间同步漫游设置时引发的事件。
我发现很多时候,即时通知(引发的事件)是不必要的。我只是在需要值时再次查询设置(例如在ready
中)。