2

我不确定这个问题的正确标题/标题应该是什么。我是 WinJS 的新手,来自 .NET webform 和 winclient 背景。

这是我的场景。我有一个导航 WinJS 应用程序。我的结构是:

  • 默认.html
    • (导航控制器)
    • (设置弹出)
  • 页面/Home.html
  • 页面/Page2.html

所以在 default.js 文件的顶部,它设置了以下变量:

var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var nav = WinJS.Navigation;

似乎我不能在我的设置弹出窗口或我的任何页面中的任何地方使用这些变量:就绪函数。它们仅适用于 default.js?

同样,互联网(链接)上是否有资源显示如何在我的每个“页面”之间正确共享变量、事件和数据?

我立即需要克服的场景是设置。在我的设置弹出窗口中,我阅读并允许用户有选择地设置以下应用程序设置:

var applicationData = Windows.Storage.ApplicationData.current;
var localSettings = applicationData.localSettings;

localSettings.values["appLocation"] = {string set by the user};

我想在我的 default.js 文件甚至我的导航页面之一中响应该事件,但我不知道在哪里“收听”。我的直觉是监听 afterhide 事件,但我如何将其范围回溯到我想监听的页面?

4

4 回答 4

2

布莱恩。码农在这里。如果你移动你提到的线条......

var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var nav = WinJS.Navigation;

...在直接函数之外,它们将在全局范围内,您可以在任何地方访问它们。这是我在应用程序中做的第一件事。您会听到有关使用全局范围的警告,但人们试图避免的是在全局范围内删除所有内容的模式。只要你控制你放在那里的东西,你就没事。

所以把它们放在 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
})();

如果您要保存一些数据并且只需要将其保存在内存中,则可以将其挂在 app 变量上,而不是将其保存到本地存储中。这将使它可用于整个应用程序。

//on Page2.js
app.myCustomVariable = "some value";

//on Page3.js
if(app.myCustomVariable == "some value") ...
于 2013-08-06T20:06:22.613 回答
1

这是我最终做的事情,它是所有给出答案的组合:

  • 创建了一个 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
于 2013-08-12T16:09:08.747 回答
1

关于您的迫切需要:

  1. 就像在另一个答案中提到的那样,您可以使用datachangedevent.

关于共享变量:

  1. 如果您希望将某些变量保留为应用程序的全局变量,则可以将它们放置在 Jeremy 答案中提到的匿名函数之外。通常,这是在 default.js 中完成的。需要确保使用全局变量的脚本放在定义全局变量的脚本之后-in default.html。通常 - 这样的变量将指向单例类。例如:我在我的一个应用程序中使用它来为应用程序的后端服务存储 authclient/serviceclient。这样 - 多个页面的视图模型不需要创建对象的实例或在 WinJS 命名空间下引用它。
  2. WinJS 也有命名空间的概念,它可以让你组织你的函数和类。例子:

    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;
        },
    }
    
  3. 使用WinJS.Navigation.navigate导航到页面时,第二个参数initialState可用作页面options就绪事件处理程序的参数。arguments除非它是应用程序数据或会话状态,否则这是传递给页面的推荐方式。应用程序数据/会话状态需要单独处理,需要单独讨论。应用导航历史由winjs库持久化;它确保如果应用程序在暂停后再次启动 - 导航时选项将再次传递到页面。最好将options对象中的属性保留为简单的原始类型。

问候事件:

  1. 通常,应用程序使用来自 winjs 库的事件。这可以通过在元素上使用addEventListener或设置事件属性等注册事件处理程序来完成。onclick事件处理程序通常在ready页面的事件处理程序中注册。
  2. 如果您正在编写自己的自定义控件,或者有时在您的视图模型中,您可能必须公开自定义事件。Winjs.UI.DOMEventMixinWinJS.Utilities.createEventProperties可以使用WinJS.Class.mix与您的类混合。例子:

    WinJS.Class.mix(MyViewModel,
        WinJS.Utilities.createEventProperties('customEvent'),
        WinJS.UI.DOMEventMixin);
    
  3. 最常用的是绑定以使您的视图模型 - 可观察。有关详细信息,请参阅相应的示例和 api 文档。例子:

    WinJS.Class.mix(MyViewModel,
        WinJS.Binding.mixin, 
        WinJS.Binding.expandProperties({ items: '' }));
    
于 2013-08-07T07:48:32.570 回答
0

当您更改需要实时更新的数据时,调用applicationData.signalDataChanged(). 然后在关心获取更改通知的地方,监听datachangedapplicationData 对象。这也是在计算机之间同步漫游设置时引发的事件。

不过,我发现很多时候不需要即时通知(引发事件)。我只是在需要值时再次查询设置(ready例如)。

于 2013-08-05T20:36:45.333 回答