2014-10-16 103 views
1

我有一個loginview和它的loginmodel。 loginmodel是從mainrouter的初始化創建的。根據loginmodel的loginp屬性,主路由器的render_home決定是否渲染homeview或導航到登錄路由,該路由調用render_loginrender_login有一個方法來save()從loginview的輸入字段填充loginmodel。所以如果數據是正確的save()響應和loginmodel更改,其loginp屬性將變爲true。所以現在應該呈現homeview。但我無法成功。將控制權從視圖傳遞迴主幹路由器?

我認爲在這一點上,控制權應該傳回到mainrouter的路線,再次調用render_home。所以它測試loginView.model.get('loginp') == true,結果爲true,所以這次創建homeview並通過已在homeview中定義的homeView.render()進行渲染。

我把一個listenTo在loginview中當它的模型改變或同步,以調用mainrouter中的路由來調用render_home。但是這種結局在這兩種觀點之間無休止的來回,沒有任何渲染。 this.listenTo(this.loginView.model, 'sync', Backbone.history.navigate("",{trigger:true}));

路線""順便指定render_home

我錯過了什麼。是否無法將控制權交還給路由器? 主路由器:

define([ 
    'jquery', 
    'ratchet', 
    'underscore', 
    'backbone', 

    'login/loginmodel', 

    'login/loginview', 
    'register/registerview', 

    'home/homeview', 
    ], 
    function($, Ratchet, _, Backbone, LoginModel, LoginView, RegisterView, HomeView){ 
     var MainRouter = Backbone.Router.extend({ 
      routes: { 
       "": "render_home", 

       "login": "render_login", 
       "register": "render_register" 
      }, 

      initialize: function(){ 
       this.loginView = new LoginView;     
      }, 

      render_home: function(){      
       this.loginView.model.fetch({ 
        success: function(model){ 
         if(model.get('loginp') == true){ //show you app view for logged in users! 
          this.homeView = new HomeView(); 
          this.homeView.render(); 
         } 
         else { //not logged in! 
          Backbone.history.navigate("/login", {trigger:true}) 
         } 
        }, 
       }); 

      }, 
      render_login: function(){ //display your login view 
       this.loginView.render(); 

      }, 
      render_register: function(){ //display your register view 
       this.registerView = new RegisterView;     
       this.registerView.render(); 
      }, 
     }); 

     return MainRouter; 
}); 

loginview:

define([ 
    'jquery', 
    'ratchet', 
    'underscore', 
    'backbone', 

    'login/loginmodel', 
    'text!login/logintemplate.html', 

    ], 
    function($, Ratchet, _, Backbone, LoginModel, LoginTemplate){ 
     var LoginView = Backbone.View.extend({ 

      el: $('body'), 

      initialize: function(){ 
       this.model = new LoginModel; 
      }, 

      template: _.template(LoginTemplate), 

      render: function(){ //display your login view 
       this.$el.html(this.template(this.model.attributes)); 
      }, 

      events: { 
       'keyup input' : 'updateform', 
       'click #loginbutton' : 'login', 
       'click #renderregisterbutton' : 'render_register', 
      }, 

      updateform: function(e){ 
       var el = e.target; 
       var formData = {}; 
       formData[ el.id ] = $(el).val(); 
       this.model.set(formData); 
      }, 

      login: function(e){ 
       e.preventDefault(); 
       this.model.save(); 
       console.log(JSON.stringify(this.model)); 
      }, 

      render_register: function(){ 
       Backbone.history.navigate("/register", {trigger:true}); 
      }, 
     }); 

     return LoginView; 
}); 

loginmodel:

define([ 
    'underscore', 
    'backbone', 
    ], 
    function(_, Backbone) { 
     var LoginModel = Backbone.Model.extend({ 

      urlRoot: '/log_in', 

      defaults: { 
       username: null, 
      }, 
     }); 

     return LoginModel; 
}); 

回答

1

你絕對可以從Route 「通過控制」 到View和後面;您render_login功能正是這麼做的:

render_login: function(){ //display your login view 
    // 1) router has control 
    this.loginView.render(); // 2) control passes to loginView 
    // 3) control passes back to the router 
}, 

但只有具有同步邏輯的作品。我認爲你遇到的問題是因爲你在render_home方法中使用異步邏輯(this.loginView.model.fetch())。異步邏輯從主執行路徑分裂了,所以render_home路徑更像是:

// 0) Router has control, and calls render_home 
render_home: function(){ 
    // 1) LoginView has control 
    this.loginView.model.fetch({ 
     success: function(model){ 
      // 4) LoginView has control once again, but now routing is done 
      if(model.get('loginp') == true){ //show you app view for logged in users! 
       this.homeView = new HomeView(); 
       this.homeView.render(); 
      } 
      else { //not logged in! 
       Backbone.history.navigate("/login", {trigger:true}) 
      } 
     }, 
    }); 
    // 2) LoginView still has control 
}, 
// 3) Control passes back to the Router, which finishes routing 

因此,由當時的fetch回報,沒有路由邏輯回來。

但是,這很容易解決:只需撥打Backbone.history.navigate(與trigger: true)從您的fetch成功處理程序。這將啓動一個新的路由過程,並且到那時(因爲fetch已經完成),LoginModel現在將被填充並且您的路由邏輯應該工作。

+0

感謝您的回覆。它給了我關於控制通行證的見解。當我添加你建議的導航時,它會在兩個視圖之間引起無限的來回。現在我已經解決了它。當我完成時我會寫。它在路由器中包含一個'this.listenTo(this.loginView.model,'change',this.render_home); //這個解決了render_home問題。' – 2014-10-17 00:22:15

+0

啊,對不起,我的解決方案沒有工作「開箱即用」(有時可能很難在沒有IDE /測試環境的情況下爲StackOverflow編寫代碼)。當你有最終的解決方案時,你可以:A)將它作爲單獨的答案發布,B)編輯我的答案並添加新的代碼,或者C)(如果你沒有編輯權限)添加新代碼作爲評論我很樂意用它更新我的答案。 – machineghost 2014-10-17 17:21:16

相關問題