5

我正在为我的主干应用程序登录并遇到一个问题,如果不调用服务器,我不知道如何解决。这在我的团队中引发了一场关于其他人如何处理这种事情的讨论,因为我们认为我们将在未来遇到类似的事情。

今天是星期五,我可能只是脑死亡,但这里...

我们有一个用户模型。View 的 login 方法创建一个新的用户模型并调用它的 login 方法,传入用户的凭据和一个回调函数,该函数具有一个包含用户信息的对象。

这是我们视图的登录方法:

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

我们试图弄清楚的是如何最好地使这个模型数据可用于另一条路线(家),以便我们可以在视图中使用它。

所以我有这个路由器:

routes: {
'': 'home',
'home': 'home',
'login': 'login'
},
home: function(data){
   console.log(data);
}

一旦我们登录了用户,我们需要更新路由并访问该用户的数据,但不希望返回服务器来获取它。

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

谢谢!

4

3 回答 3

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
}

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

对不起,我没有灵丹妙药给你。有一些库,其中有Backbone.StateManager,它们可以帮助管理状态、转换等,但本质上它们不会做任何你不能为自己做的事情。

于 2013-01-04T21:43:21.780 回答
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);

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

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

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

于 2013-01-04T20:31:33.827 回答
0

现在回复为时已晚,但是根据您使用的路由器引擎并且没有局部变量,还有另一种更好的方法可以做到这一点。我将尝试使用适用于所有人的骨干给出一个通用示例。

通常,您的路由器将在一个处理事情的地方。假设它的主干让路由定义如下。

var router = Backbone.Router.extend({
routingData: {}, // this will have the routing data
routes: {
    '': 'home',
    'home': 'home',
    'login': 'login'
},
navigate: function(url, data) {
    this.routingData["data"] = data; // whenever navigation is done, this will be reset
    //This is the routing code whichever the f/w may be.
    Backbone.Router.prototype.navigate(route, { trigger: true });
},
home: function(data) {
    var params = this.routingData["data"]; //retreiving the routing params
    console.log(params);
}
})

现在如果你想传递数据,你可以做

router.navigate(<URL>,<SOME DATA>)
于 2016-09-13T19:04:21.763 回答