【问题标题】:Render backbone template when myModel.fetch() is done?myModel.fetch() 完成后渲染主干模板?
【发布时间】:2014-07-18 10:35:13
【问题描述】:

使用backbone.js 我正在尝试从我的服务器获取一个模型,并在此基础上呈现一个下划线模板。我首先尝试使用以下渲染函数而不使用 api 调用的结果:

render: function(options) {
    this.ticketId = options.ticketId;
    var that = this;
    var ticketModel = new TicketModel({'id': that.ticketId});
    $.when(ticketModel.fetch()).done(function(){
        console.log(ticketModel); // this outputs the correct model
    });
    var template = _.template($('#tab-content-template').html(), {ticketId: that.ticketId});
    this.$el.html(template);
},

这很好用。所以我尝试使用api调用的结果来渲染模板:

render: function(options) {
    this.ticketId = options.ticketId;
    var that = this;
    var ticketModel = new TicketModel({'id': this.ticketId});
    $.when(ticketModel.fetch()).done(function(){
        console.log(ticketModel);
        console.log($('#tab-content-template').html());
        var template = _.template($('#tab-content-template').html(), {ticketId: that.ticketId});
        this.$el.html(template);
    });
},

但不幸的是,这会导致错误提示

Uncaugt TypeError:无法读取未定义的属性“html”。

奇怪的是它在控制台中正确输出了由console.log($('#tab-content-template').html()); 生成的html。我得到的错误是this.$el.html(template);

怎么会先能拿到html(),然后又说找不到属性html呢?我完全被困在这里..:S

欢迎所有提示!

【问题讨论】:

  • 从中学到了一些新东西,没有意识到 fetch 返回了 $.deferred 对象,干杯

标签: javascript jquery templates backbone.js underscore.js


【解决方案1】:

您的问题是 this 不再是指您认为它所指的内容。在您放置的代码中

var that = this;

这是一种常见的模式/技巧,允许闭包在执行时保留“this”的上下文。在你的闭包中,“that”现在指的是你认为“this”应该指的东西。

试着把“这个”改成“那个”

 $.when(ticketModel.fetch()).done(function(){
        console.log(ticketModel);
        console.log($('#tab-content-template').html());
        var template = _.template($('#tab-content-template').html(), {ticketId: that.ticketId});
        that.$el.html(template);
    });

我通常使用 jQuery 的代理函数来确保当一个函数被执行时你可以确信它正在运行的上下文

 $.when(ticketModel.fetch()).done($.proxy(function(){
        console.log(ticketModel);
        console.log($('#tab-content-template').html());
        var template = _.template($('#tab-content-template').html(), {ticketId: that.ticketId});
        this.$el.html(template);
    },this));

哦,关于为什么 $('#tab-content-template').html() 工作的另一个问题,这是因为您直接使用全局命名空间中的 JQuery,因此可以访问 $el 所在的位置视图的属性,因此如果您无法访问视图,则无法访问该属性。

【讨论】:

  • @kramer65 这解决了您的问题吗?
【解决方案2】:

参见http://backbonejs.org/#Model-fetch - 在options 参数中它接受successerror 回调:

ticketModel.fetch({
    success: function(model, response, options) {
        // render the template
    }
});

此外,如果您需要在此回调中使用当前视图对象的上下文,您可以使用 Underscore/Lo-Dash _.bind() 函数来传递上下文:

ticketModel.fetch({
    success: _.bind(function(model, response, options) {
        // Render the template using some method of the view:
        this.renderMyTemplate(model);
    }, this)
});

或者只是传递方法本身:

ticketModel.fetch({
    success: this.renderMyTemplate,
    error: this.handleFetchError
});

【讨论】:

    【解决方案3】:

    你不需要 $.when 在这里,主干现在返回一个 fetch 调用的承诺。下面的代码应该适合你。还可以考虑在渲染函数之外编译模板。编译模板有点繁重,完成后要缓存。

    var _this = this;
    ticketModel.fetch().done(function () {
        var template = _.template($('#tab-content-template').html(), {ticketId: that.ticketId});
        _this.$el.html(template);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-09
      • 1970-01-01
      • 1970-01-01
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多