2015-12-11 70 views
-1

當我嘗試將路由器的公共變量this.currentView關聯到新創建的視圖時,視圖會丟失,公共變量爲空而不是包含新創建的視圖。路由器在創建後丟失的骨幹視圖

var self=this; 

     var watchListsCollection = new WatchlistCollection; 
     watchListsCollection.url = "watchlists"; 
     user.fetch().done(function() { 
      watchListsCollection.fetch().done(function() { 
       loggedUser.fetch().done(function() { 

        self.currentView = new UserView(user, watchListsCollection,loggedUser); 

       }); 
      }); 
     }); 

     alert(this.currentView); //null 

回答

0

fetch()呼叫你是射擊異步AJAX請求,在你done處理程序意味着代碼不會被執行,直到服務器調用返回。一旦你執行了user.fetch(),瀏覽器將發出一個請求,然後繼續運行你的程序並提醒this.currentView而不必等待請求完成。

事件的順序基本上將是

  1. 呼叫user.fetch()
  2. 警報this.currentView
  3. 呼叫watchListsCollection.fetch()
  4. 呼叫loggedUser.fetch()
  5. 設置的self.currentView

在最後一次服務器請求完成之前,您將無法看到currentView的值。

如果你改變你的代碼

var self=this; 

var watchListsCollection = new WatchlistCollection; 
watchListsCollection.url = "watchlists"; 
user.fetch().done(function() { 
    watchListsCollection.fetch().done(function() { 
     loggedUser.fetch().done(function() { 

      self.currentView = new UserView(user, watchListsCollection,loggedUser); 
      alertCurrentView(); 
     }); 
    }); 
}); 

function alertCurrentView() { 
    alert(this.currentView); 
} 

您應該看到顯示正確的值。現在,取決於您打算如何使用您的this.currentView,因爲這可能會或可能不會讓您解決您遇到的任何問題,但無法在所有請求可用之前不必等待所有請求完成。如果您需要立即採取措施,您應立即創建UserView,並將fetch()電話轉入該視圖的initialize()

0

fetch()是異步的,但在開始任務後檢查變量。可能這些任務,因爲他們應該只是讀取,應該平行運行。而忘記做的this副本,而不是根據製作的Airbnb風格指南嘗試_.bindhttps://github.com/airbnb/javascript

var tasks = []; 
tasks.push(user.fetch()); 
tasks.push(watchListsCollection.fetch()); 
tasks.push(loggedUser.fetch()); 

Promise.all(tasks).then(_.bind(function() { 
    this.currentView = new UserView(user, watchListsCollection, loggedUser); 
}, this)); 

或使用ES6發電機:

function*() { 
    var tasks = []; 

    tasks.push(user.fetch()); 
    tasks.push(watchListsCollection.fetch()); 
    tasks.push(loggedUser.fetch()); 

    yield Promise.all(tasks); 

    this.currentView = new UserView(user, watchListsCollection, loggedUser); 
} 
+1

如果你打算使用承諾或發電機你還不如使用'Function.prototype.bind'而不是'_.bind'。它從IE9開始工作:) – ivarni