Backbone:销毁以前的视图并使用Router

时间:2014-03-03 21:38:27

标签: javascript backbone.js

这是一个登录流程,用户在其中提供登录详细信息并从服务器获取响应。
在这里,我无法弄清楚我应该在哪里删除以前的视图? dashboard View是否需要了解LoginView Router有什么用?在这种情况下,流量是否会流入路由器?
两种观点

var LoginView = Backbone.View.extend({
    url: 'http://localhost:3000/login',
    template:_.template('<div class="form-signin">'+
                        '<h2 class="form-signin-heading">Please sign in</h2>'+
                        '<input type="text" id="email" class="form-control" placeholder="Email address" required="" autofocus="">'+
                        '<input type="password" id="password" class="form-control" placeholder="Password" required="">'+
                        '<button id="loginBtn" href="#login" class="btn btn-lg btn-primary btn-block" >Sign in</button>'+
                        '</div>'),
    events: {
        "click #loginBtn":"login"
    },
    initialize: function() {
        this.model.on('change', this.render, this); 
    },
    render: function() {
        var attributes = this.model.toJSON();
        this.$el.html(this.template(attributes));
    },
    login: function() {
      console.log('view signIn');
      this.model.set({
        "email": $('#email').val(),
        "password": $('#password').val()
      });
      this.model.login();
    }
});

var DashboardView = Backbone.View.extend({
    template:_.template('<div>'+
                        '<h3><%= campaignName %></h3>'+
                        '<span><%= orderedAndGoal %>, </span>'+
                        '<span><%= status %>, </span>'+
                        '<span><%= endDate %>, </span>'+
                        '</div>'),
    initialize: function() {
        this.model.on('change', this.render, this); 
    },
    render: function() {
        console.log('what happens here')
        var attributes = this.model.toJSON();
        this.$el.html(this.template(attributes));
            this.$el.appendTo('.container');
    },
});
var dashboardView = new DashboardView({model: dashboardModel});

两种模式

var LoginModel = Backbone.Model.extend({
    url:'http://localhost:3000/login',

    defaults: {
        email:"",
        password:""
    },
    parse: function(resp) {
        console.log('Model: Got the response back');
        return resp;
    },
    login: function() {
        console.log('Model: Login function:'+JSON.stringify(this));
        this.save(
            {}, {
                success: function(resp) {
                    console.log('success'+JSON.stringify(resp.get("0")));
                    dashboardModel.set(resp.get("0"));
                    //window.location = 'templates/dashboard.html'
                },
                error: function(error) {
                    console.log('error: '+JSON.stringify(error));
                }
            });
    },
    redirect: function() {
        console.log('inside redirect method');
    }
});
var loginModel = new LoginModel();

var DashboardModel = Backbone.Model.extend({
    defaults: {
        campaignName:"",
        orderedAndGoal:"",
        status:"",
        endDate:"",
        orderPlace:"",
        tShirtOrdered:"",
        tippingPoint:"",
        getPaid:""
    },
    parse: function(resp) {
        console.log('Model: Got the response back');
        return resp;
    }
});
var dashboardModel = new DashboardModel();

LoginModel.save()从服务器获取值并将其设置为DashboardModel时。 DashboardView听取模型的变化。然后它调用render()。这一切都有道理。但那之后去哪儿? 将DashboardView.el附加到其render()中的父标记是否是一个好主意? 这里是否有Router的使用?
应用程序的路由器如下所示:

var Router = new (Backbone.Router.extend({
    routes: {
        "":"home",
        "login":"login"
    },
    start: function() {
        Backbone.history.start({pushState:true});
    },
    home: function() {
        var loginView = new LoginView({model: loginModel});
        loginView.render();
        $(".container").append(loginView.el);
    }, 
    login: function() {
        var loginModel = new LoginModel();
        var loginView = new LoginView({model: loginModel});
        loginModel.fetch();     
    }
}));

new Router.start();

2 个答案:

答案 0 :(得分:1)

您的问题

  1. 在这里,我无法弄清楚我应该在哪里删除以前的视图?

    A:可以在DOM中替换或追加视图,具体取决于应用需求。

  2. 仪表板视图是否需要了解LoginView?

    A:视图无需了解其他视图。将此职责传递给路由器/控制器,或将数据保存在两个视图可共享的通用模型中。

  3. 路由器有什么用?在这种情况下,流量是否会流向路由器?

    A: Backbone路由器会监听网址更改,但它们是收听视图事件的正确位置,因此如果您的视图进行了重大更改,则可以做出相应的反应。这来自Backbone文档:

      

    Backbone.Router提供了路由客户端页面的方法,并将它们连接到操作和事件。

  4. 您的示例

    在您提供的代码中,两条路线都会创建一个登录视图:

    home: function() {
        var loginView = new LoginView({model: loginModel});
        loginView.render();
        $(".container").append(loginView.el);
    },
    login: function() {
        var loginModel = new LoginModel();
        var loginView = new LoginView({model: loginModel});
        loginModel.fetch();
    }
    

    您可以做的是拥有登录路线和仪表板的其他路线:

    • 登录路径,创建视图,登录成功后,将会话保存在cookie中。
    • 在仪表板路径中,您检查会话是否可用,并且仅在内容存在时呈现内容,如果不是,则重定向到登录。

    有很多关于用户身份验证的好文章,我指的是this example

答案 1 :(得分:0)

您可以将视图附加到DOM中的元素。您可以在渲染后执行此操作:

render: function() {
    console.log('what happens here')
    var attributes = this.model.toJSON();
    this.$el.html(this.template(attributes));
    this.$el.appendTo('#yourElement');
},

或者,您可以设置在创建视图时查看附加元素:

var dashboardView = new DashboardView({
                        model: dashboardModel,
                        el: $('#yourElement')
                    });

此外,如果您想用您的DashboardView替换您的loginView,您需要.remove()旧视图并将DashboardView附加到同一个容器元素。