在不进入服务器的情况下在路由之间保留数据?

Cha*_*les 5 backbone.js

我正在为我的主干应用程序登录并遇到一个问题我不知道如何在不调用服务器的情况下解决.这引发了我的团队讨论其他人在骨干中处理这种事情的方式,因为我们认为我们将会遇到类似的事情.

这是星期五,我可能只是脑死了,但这里......

我们有一个用户模型.View的登录方法创建一个新的用户Model并调用它的登录方法传递用户的凭据和一个回调函数,该函数有一个包含用户信息的对象.

这是我们的View的登录方法:

login: function(event){
    event.preventDefault();

    var user = new App.User;
    user.login($('#username').val(), $('#password').val(), 
        (function(msg) {
            // success callback
            if (msg.loggedIn) {
                console.log("Authenticate successful: " + JSON.stringify(msg));
                var data = { user : msg, bob : "bob", trigger:true };
                console.log("Prepared data: " + JSON.stringify(data));
                App.router.navigate('home',data);
            } else {
                console.log("Authenticate unsuccessful: " + JSON.stringify(msg));
            }
        }).bind(this), 
        function(msg) { 
            // failure callback
            console.log("Authenticate communication failure: " + JSON.stringify(msg));
            alert("Communication fail!"); 
            App.router.navigate('login',{trigger:true}); 
        });
}
Run Code Online (Sandbox Code Playgroud)

我们想要弄清楚的是如何最好地将这个模型数据提供给另一个路径(home),以便我们可以在View中使用它.

所以我有这个路由器:

routes: {
'': 'home',
'home': 'home',
'login': 'login'
},
home: function(data){
   console.log(data);
}
Run Code Online (Sandbox Code Playgroud)

一旦我们记录了用户,我们需要更新路由并访问该用户数据,但不希望必须返回服务器才能获取它.

我担心的是因为我们正在构建一种"向导",用户可能需要前进和后退一些步骤,我不希望每次浏览应用程序时都要点击服务器,但它看起来像我们要么需要将东西保存到全局变量(不想这样做),要么每次都要返回服务器.我相信其他人不得不处理类似的问题.只是寻找一些见解.

谢谢!

jev*_*lio 5

"看起来我们要么需要将内容保存到全局变量中(不想这样做)"

说明显而易见的:你将需要保持国家.您可以选择将状态转移到服务器并返回,或者在客户端上保持状态.由于您已经确定不希望通过服务器传递状态,因此您将在客户端上的不同页面(路由)之间保留状态.

这就是全局变量的用途.我知道这听起来很蹩脚,但它也是单页应用程序带来的主要好处之一.有状态.而且这种状态总是由一些全球性的对象来控制.

管理国家的方式越来越好.有一个全局变量被称为data你继续分配和重新分配显然是最糟糕的方式.你应该找出一个对你的要求有意义的模式.

如果我正确理解您的代码示例,您要存储的是有关当前用户的信息.您似乎已经拥有了一个全局变量App.在我看来,保留某种session信息是个好主意:

login: function(data){
    doLogin({
        success: function(userData) {
            App.session.currentUser = userData;
            App.router.navigate('home', { trigger:true });
        }
    });
},

home: function(data){
    if(!App.session || !App.session.currentUser) {
        App.router.navigate('login', { trigger:true });
        return;
    }

    var user = App.session.currentUser;
    //do something with user
}
Run Code Online (Sandbox Code Playgroud)

国家不一定是邪恶的.什么是邪恶取决于整个应用程序的全局状态,这很容易导致不可测试的意大利面条代码.但是,如果你解决国家的依赖作为链尽可能地(例如路由器)"高达",并使用构造函数和方法参数值传递下去,你仍可以保持可测性和侧effectlessness中的其余部分代码库.

对不起,我没有你的银弹.其中有一些库,Backbone.StateManager,它们可以帮助管理状态,转换等,但实质上它们不会做任何你不能做的事情.


Sud*_*jee 1

使用本地存储!

修改您的代码以执行以下操作:

       // success callback
        if (msg.loggedIn) {
            console.log("Authenticate successful: " + JSON.stringify(msg));
            var data = { user : msg, bob : "bob", trigger:true };
            var dataString = JSON.stringify(data);
            console.log("Prepared data: " + dataString;
            window.localStorage.setItem("userdata",dataString);
            App.router.navigate('home',data);
Run Code Online (Sandbox Code Playgroud)

现在,每当您需要检查用户是否登录时,请执行以下操作:

try {
    var userData = window.localStorage.getItem ("userdata");
} catch (e) {
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

try-catch 是必要的,以确保如果身份验证从未成功,您的代码不会崩溃。