Javascript 如何在启动视图之前等待模型初始化

Javascript 如何在启动视图之前等待模型初始化,javascript,backbone.js,Javascript,Backbone.js,我正在制作一个基本的trello克隆。除了没有登录之外,项目有一个slug(即“www.example.com/1d754b6c”) 如果用户访问根目录,将在后端创建一个新的slug。然后将用户路由到www..com/1d754b6c,后者发送另一个ajax调用以获取项目ID。然后启动一个视图。但是,我的视图是在slug->ID ajax调用完成之前开始的。解决这个问题的最好方法是什么?(我目前有一个setTimeout作为临时补丁,我知道这不是一个好办法) 路由器.js Buckets.Rou

我正在制作一个基本的trello克隆。除了没有登录之外,项目有一个slug(即“www.example.com/1d754b6c”)

如果用户访问根目录,将在后端创建一个新的slug。然后将用户路由到www..com/1d754b6c,后者发送另一个ajax调用以获取项目ID。然后启动一个视图。但是,我的视图是在slug->ID ajax调用完成之前开始的。解决这个问题的最好方法是什么?(我目前有一个setTimeout作为临时补丁,我知道这不是一个好办法)

路由器.js

Buckets.Routers.PageRouter = Backbone.Router.extend({
    routes: {
        '': 'newProject',
        ':token': 'displayProject'
    },
    newProject: function () {
        new Buckets.Models.Project({});
    },
    displayProject: function (token) {
        var that = this;
        var project = new Buckets.Models.Project({token: token});
        setTimeout(function(){ 
            new Buckets.Views.showProject({
                            model: project
                        });
        }, 500);

    }
});
project.js

Buckets.Models.Project = Backbone.Model.extend({
    url: function() {
        return Buckets.BASE_URL + '/api/projects/' + (this.id)
    },
    initialize: function(options) {
        var that = this;
        if (options && options.token) {
            that.token = options.token
            $.ajax({
                url: Buckets.BASE_URL + '/' + that.token,
                dataType: 'json',
                    success: function( data, status ){
                        that.id = data;
                    },
                    error: function(xhr, textStatus, err) {
                        console.log(xhr);
                    }
                });
        } else {
            $.ajax({
                    url: Buckets.BASE_URL + '/api/projects/new', 
                    dataType: 'json',
                    success: function( data, status ){
                        that.token = data.token;
                        that.id = data.id;
                        Buckets.Routers.router.navigate('/' + that.token, true);
                    },
                    error: function(xhr, textStatus, err) {
                        console.log(xhr);
                    }
                });
        }
        return this;
    },
});

尝试使用
主干.Model.sync
.sync()
返回一个承诺,以便您可以充分利用不同的/承诺标准

当我想将变量URL传递给fetch时,我会覆盖
model.fetch()
。对于您的实现,我首先在
initialize()
中废弃
$.ajax
,并像这样覆盖
fetch

Buckets.Models.Project = Backbone.Model.extend({
  fetch: function(options) {
      var that = this;
      if (options && options.token) {
        this.url = Buckets.BASE_URL + '/' + that.token;
      else
        this.url = Buckets.BASE_URL + '/api/projects/new';

      return Backbone.Model.prototype.fetch.call(this, options);
}
.fetch()
最终返回
sync()
的结果,这是一个承诺。这意味着,在
路由器中,您将执行以下操作:

displayProject: function (token) {
  var that = this;
  var project = new Buckets.Models.Project();
  $.when(project.fetch({token: token})
  // deffered.done() replaces the success callback in your $.ajax
  .done(function() {
    project.id = data;
    new Buckets.Views.showProject({ model: project });
  })
  // deffered.fail() replaces the error callback in your $.ajax
 .fail(function( jqXHR, textStatus, errorThrown) {
   console.log(jqXHR);
 });
}
为了完整性,您需要同样地重写
newProject()

newProject: function () {
  var project = new Buckets.Models.Project();
  $.when(project.fetch({token: token})
  .done(function( data, textStatus, jqXHR ) {
    project.token = data.token;
    project.id = data.id;
    new Buckets.Views.showProject({ model: project });
  })
  .fail(function( jqXHR, textStatus, errorThrown) {
    console.log(jqXHR);
  });
}
试试看。我开始使用这种抓取方法时,一位主要贡献者向我推荐了
marionetejs
,这是一种主要的自以为是的主干框架。该方法易于维护,响应速度快