WinJS变量/对象范围、设置和事件



我不确定这个问题的正确标题/标题应该是什么。我是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") ...

关于您的迫切需求:

  1. 正如在另一个答案中提到的,您可以使用datachanged事件

关注共享变量:

  1. 如果有一些变量希望对应用程序保持全局性,则可以将它们放置在Jeremy答案中提到的匿名函数之外。通常,这是在default.js中完成的。需要确保使用全局变量的脚本位于定义全局变量的剧本之后-在default.html中。通常,这样的变量将指向singleton类。例如:我在我的一个应用程序中使用它来存储应用程序后端服务的authclient/serviceclient。这样,多个页面的视图模型就不需要创建对象的实例,也不需要在WinJS命名空间下引用它
  2. 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;
        },
    }
    
  3. 当使用WinJS.Navigation.Navigation导航到页面时,第二个参数initialState可用作该页面的就绪事件处理程序的options参数。这将是向页面传递arguments的推荐方式,除非这是应用程序数据或会话状态。应用程序数据/会话状态需要单独处理,并且需要单独讨论。应用程序导航历史记录由winjs库持久化;它确保了如果应用程序在暂停后再次启动-导航时选项将再次传递到页面。最好将options对象中的属性保持为简单的基元类型。

问候事件:

  1. 通常,应用程序使用winjs库中的事件。这可以通过使用addEventListener注册事件处理程序或在元素上设置onclick等事件属性来实现。事件处理程序通常在页面的ready事件处理程序中注册
  2. 如果您正在编写自己的自定义控件,或者有时在视图模型中,则可能需要公开自定义事件。Winjs.UI.DOMEventMixin、Winjs.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: '' }));
    

以下是我最终所做的,这是所有答案的组合:

  • 创建了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中)。

最新更新