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

时间:2013-08-05 20:17:36

标签: windows-runtime winjs

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

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

  • default.html中
    • (导航控制器)
    • (设置弹出窗口)
  • 页/ Home.html中
  • 页/ Page2.html

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

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

似乎我无法在我的设置弹出窗口或任何页面中的任何位置使用这些变量:ready ready。它们只限于default.js?

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

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

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

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

我想在default.js文件或我的某个导航页面中回复该事件,但我不知道在哪里“收听”。我的直觉是听取后隐藏事件,但我如何将其范围扩展到我想听的页面?

4 个答案:

答案 0 :(得分:2)

布赖恩。 codefoster在这里。如果你移动你提到的那条线......

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") ...

答案 1 :(得分:1)

关于您的迫切需求:

  1. 如在其他答案中提到的那样,您可以使用datachanged事件。
  2. 关注共享变量:

    1. 如果您希望保持应用程序的全局变量,可以将它们放在匿名函数之外,如Jeremy答案中所述。通常,这是在default.js中完成的。需要确保在定义全局变量的脚本之后放置使用全局变量的脚本 - 在default.html中。通常 - 这样的变量将指向单例类。例如:我在我的一个应用程序中使用它来存储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.navigate导航到某个页面时,第二个参数initialState可用作该页面的ready事件处理程序的options参数。这是将arguments传递给页面的推荐方法,除非它是应用程序数据或会话状态。应用程序数据/会话状态需要单独处理,并且需要单独进行讨论。应用程序导航历史记录由winjs库保留;它确保如果应用程序在暂停后再次启动 - 选项将在导航时再次传递到页面。最好将options对象中的属性保存为简单的基本类型。

    4. 关注事件:

      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: '' }));
        

答案 2 :(得分: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

答案 3 :(得分:0)

当您更改需要实时更新的数据时,请致电applicationData.signalDataChanged()。然后在关注获取更改通知的位置,听取applicationData对象上的datachanged。这也是在计算机之间同步漫游设置时引发的事件。

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