使用Durandal的单个网页应用程序的全局变量 [英] Global variables for a single web page application using Durandal

查看:156
本文介绍了使用Durandal的单个网页应用程序的全局变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序有三个全局的东西:具有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);
});
返回router.activate();
};

然后再次进入:



welcome.js

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

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



我只想使用pub / sub,但后来觉得我会遇到鸡当数据加载相对于页面加载时,egg发出问题(IE如果我的AJAX首先被加载,而我的页面没有加载,则事件触发,但页面永远不会得到更新)。



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

解决方案

当一个 require.js 模块返回一个对象时,该对象是一个单例,所以你可以使用

settings.js

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

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


My application has three things that are "global": a user location with lat and lng values, if the user is logged in or not, and the activity that they have chosen (think of it like a category).

What I'd like to happen is for these values to be used across the application. Each screen will use some set of this date, so loading it per page isn't the right answer. The information also will not change unless the user creates an event: different location, activity, or signs in/out.

How should I set this up?

My thinking is that there should be an initial load upon startup, in my main.js file I load each and then app.start like so:

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

});

This does make sure that the data is loaded. From there in each of my services I store the information into local storage so I don't have to keep firing off AJAX calls. If local storage isn't there it will.

The problem comes later when I need this data in other pages. I'm ending up calling my site.init().then() within each page's activate method. Which is pretty sloppy.

shell.js

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

and then again in:

welcome.js

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

I'd like to set the values initially, each page initially loading from those values, and then use the pub/sub of Durandal to react to any changes after the fact.

I was thinking of solely using the pub/sub, but then felt that I would run into chicken and the egg issues when the data is loaded in relation to the page loads (IE If my AJAX loaded first, and my page wasn't loaded, the event fires, but the page never gets the update).

Is it possible to setup something like a static class in javascript to pull the data initially and then share it throughout the viewmodels? Or, is there a way to guarantee that the value will be there when I initially load a page, like a app.on('value', { initialize: true })?

解决方案

When a require.js module returns an object, that object is a singleton, so you can have something like

settings.js

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

Then any time you name settings as a dependency, you'll always get a reference to the same object and you can get/set its fields as you wish.

这篇关于使用Durandal的单个网页应用程序的全局变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆