路由器中的骨干视图在创建后丢失

时间:2015-12-11 21:47:03

标签: variables object backbone.js view router

当我尝试将路由器的公共变量this.currentView与新创建的视图相关联时,视图会丢失,公共变量为null,而不是包含新创建的视图。

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

2 个答案:

答案 0 :(得分:0)

您执行的fetch()调用正在触发异步AJAX请求,这意味着在done处理程序中的代码将不会被执行,直到服务器调用返回。执行user.fetch()后,浏览器将触发请求,然后继续运行您的程序并提醒this.currentView,而无需等待请求完成。

事件的顺序基本上是

  1. 致电user.fetch()
  2. 提醒this.currentView
  3. 致电watchListsCollection.fetch()
  4. 致电loggedUser.fetch()
  5. 设置self.currentView
  6. 的值

    在最后一次服务器请求完成之前,您将无法看到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()

答案 1 :(得分: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);
}