使用Durandal的单个网页应用程序的全局变量

时间:2014-01-07 23:18:52

标签: javascript knockout.js durandal durandal-2.0

我的应用程序有三个“全局”的东西:具有lat和lng值的用户位置(如果用户是否登录),以及他们选择的活动(将其视为类别)。

我想要发生的是在整个应用程序中使用这些值。每个屏幕都会使用这个日期的一些设置,因此每页加载它不是正确的答案。除非用户创建事件,否则信息也不会更改:不同的位置,活动或登录/退出。

我该如何设置?

我的想法是,启动时应该有一个初始加载,在我的main.js文件中我加载每个,然后app.start像这样:

siteService.js

define([...], function (...) {
    return {
        init: function () {
            return $.when(
                activityService.getStoredActivity(),
                locationService.getStoredLocation(),
                userService.getUsername()
            );
        }
    }
});

main.js

define([...,'modules / siteService'],function(...,site){     ...

site.init().then(function () {
    app.start().then(function () {
        ...
        app.setRoot('viewmodels/shell', 'entrance');
    });
});

});

确保加载数据。从我的每个服务中,我将信息存储到本地存储中,因此我不必继续触发AJAX调用。如果不存在本地存储。

当我在其他页面中需要此数据时,问题会出现。我最终在每个页面的activate方法中调用了我的site.init()。then()。这很邋。

shell.js

self.activate = function () {
            ...
    siteService.init().then(function (activity, location, username) {
        self.activity(activity);
        self.location(location);
        setUsername(username);
    });
    return router.activate();
};

然后又来了:

welcome.js

this.activate = function () {    
     site.init().then(function(activity, location) {
           loc = location;
           act = activity;
           load();
       });
});

我想最初设置值,每个页面最初从这些值加载,然后使用Durandal的pub / sub对事后的任何更改做出反应。

我在考虑单独使用pub / sub,但后来觉得我会遇到鸡和鸡蛋问题,当加载数据与页面加载相关时(IE如果我的AJAX首先加载,我的页面没有加载,事件触发,但页面永远不会得到更新。

是否有可能在javascript中设置类似静态类的东西来最初提取数据然后在整个视图模型中共享它?或者,有没有办法保证在我最初加载页面时该值将存在,例如app.on('value',{initialize:true})?

2 个答案:

答案 0 :(得分:8)

require.js模块返回一个对象时,该对象是一个单例,所以你可以有类似的东西

<强> settings.js

define(function() {
  return {
    location: {
      lat: 0,
      long: 0
    },
    loggedin: false,
    activity: ""
  }
});

然后,只要您将settings命名为依赖项,您将始终获得对同一对象的引用,并且您可以根据需要获取/设置其字段。

答案 1 :(得分:2)

siteService.js 更改为:

define([...], function (...) {
    var module = function () { };

    module.prototype.activity = {};
    module.prototype.location = {};
    module.prototype.username = {};

    module.prototype.init = function () {
        return $.when(
            activityService.getStoredActivity(),
            locationService.getStoredLocation(),
            userService.getUsername()
        ).then(function (activity, location, username) {
            module.prototype.activity = activity;
            module.prototype.location = location;
            module.prototype.username = username;
        });
    };

    return module;
});

main.js

define([..., 'modules/siteService'], function(..., Site) {
    site = new Site();
    site.init().then(function () {
        app.start().then(function () {
            ...
            app.setRoot('viewmodels/shell', 'entrance');
        });
    });

shell.js welcome.js 现在只需使用:

        var site = new Site();
        self.activity(site.activity);
        self.location(site.location);
        setUsername(site.username);

        var site = new Site();
        loc = site.location;
        act = site.activity;