2015-12-11 2 views
-1

Когда я пытаюсь связать публичную переменную моего маршрутизатора this.currentView с вновь созданным представлением, представление теряется, общедоступная переменная имеет значение null, а не только новое созданное представление.backbone view в маршрутизаторе, потерянном после создания

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

Вы не сможете увидеть значение своего текущего окна до того, как завершится последний запрос сервера.

Если вы измените код

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, попробуйте _.bind вместо согласно стилистический справочник Airbnb: https://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

Смежные вопросы