Backbone.js:this.model未定义

时间:2013-03-01 15:19:58

标签: javascript backbone.js url-routing

我花了两周时间尝试学习Backbone.js,然后用Require.js模块化应用程序。但似乎在初始化和获取过程中我没有得到任何东西。

我有两条路线,一条显示整个系列,另一条只显示一个单独的模型。我希望能够使用这两种路线启动应用程序。

如果我开始加载集合网址以及稍后在单个模型网址上加载,一切都按预期工作。如果我使用到单个模型的url路径启动应用程序,我在视图上收到错误:TypeError: this.model is undefined this.$el.html(tmpl(this.model.toJSON()));

如果我为模型设置默认值,它会渲染视图但不会使用实际数据获取它。我也试过在没有任何运气的情况下处理模型的fetch函数中的成功事件。

router.js

define(['jquery','underscore','backbone','models/offer','collections/offers','views/header','views/event','views/offer/list', 
], function($, _, Backbone, OfferModel, OffersCollection, HeaderView, EventView, OfferListView){

var AppRouter = Backbone.Router.extend({    

routes: {
    'event/:id' : 'showEvent',
  '*path': 'showOffers'
},

initialize : function() {       
    this.offersCollection = new OffersCollection();
    this.offersCollection.fetch();
    var headerView = new HeaderView();
    $('#header').html(headerView.render().el);          
},

showEvent : function(id) {
    if (this.offersCollection) {
        this.offerModel = this.offersCollection.get(id);
    } else {
        this.offerModel = new OfferModel({id: id});
        this.offerModel.fetch();
    }       
    var eventView = new EventView({model: this.offerModel});    
    $('#main').html(eventView.render().el);     
},

showOffers : function(path) {
    if (path === 'betting' || path === 'score') {
        var offerListView = new OfferListView({collection: this.offersCollection, mainTemplate: path});  
      $('#main').html(offerListView.render().el) ;       
    }       
},    
});

var initialize = function(){    
  window.router = new AppRouter;
  Backbone.history.start();
};

return {
  initialize: initialize
};
});

视图/ event.js

define(['jquery','underscore','backbone','text!templates/event/main.html',
], function($, _, Backbone, eventMainTemplate){

var EventView = Backbone.View.extend({
    initalize : function(options) {
        this.model = options.model; 
        this.model.on("change", this.render);       
    },

    render : function() {
        var tmpl = _.template(eventMainTemplate);
        this.$el.html(tmpl(this.model.toJSON()));
        return this;
    }
});

return EventView;   
});

1 个答案:

答案 0 :(得分:1)

您正在路由器的initialize方法中创建和提取OffersCollection,因此else中的showEvent块永远不会被命中,因为this.offersCollection始终是真的。< / p>

评论之后,我认为你需要这样做:

showEvent : function(id) {
    var that = this;
    var show = function(){
       var eventView = new EventView({model: that.offerModel});    
       $('#main').html(eventView.render().el); 
    };
    // offersCollection is always defined, so check if it has the model
    if (this.offersCollection && this.offersCollection.get(id)) {
        this.offerModel = this.offersCollection.get(id);
        show();
    } else {
        this.offerModel = new OfferModel({id: id});
        this.offerModel.fetch().done(function(){
           // model is fetched, show now to avoid your render problems.
           show();
        });
        // alternatively, set the defaults in the model,
        // so you don't need to wait for the fetch to complete.
    }       

}