具有服务器端呈现的HTML片段的骨干模型

时间:2012-09-08 16:05:02

标签: javascript html json backbone.js

我想开始使用Backbone.js来更好地构建我的JavaScript文件。但是,我不想重做我的应用程序只通过API输出JSON。如果我错了,请纠正我,但到目前为止,我的印象是即使没有JSON API,我仍然可以使用Backbone.js。现在我遇到了一个问题,我的服务器返回HTML并且Backbone模型不喜欢它并返回错误。

基本上,我想根据类别加载HTML代码段:

var Filter = Backbone.Model.extend({
    url: '/filters/',
});
var FilterView = Backbone.View.extend({
    initialize: function() {    
        this.model.on('change', this.updateFilter, this);
        this.changeFilter();
    },

    changeFilter: function() {
        this.model.fetch({data: $.param({category: this.options.category})});
    },

    updateFilter: function(filters) {
        console.log(filters);
        this.$el.html(filters);
    },
});

var filter = new Filter();
var filterView = new FilterView({
    el: $( '#filterContainer' ),
    category: $( '#categorySlug' ).data( 'slug' ),
    model: filter,
});

现在我认为我可以使用这个简单的模型通过Ajax检索我的HTML片段。请求正确触发,但Backbone返回错误,updateFilter永远不会被调用。

我没有得到什么?我需要更改什么才能使其与HTML一起使用而不是JSON响应?或者我不应该使用模型?

5 个答案:

答案 0 :(得分:3)

您需要扩展Backbone模型以覆盖fetch,以便与lost的答案一样,您需要将数据类型传递给Backbone.Sync

fetch: function(options) {
    return Backbone.Model.prototype.fetch.call(this, _.extend({ dataType: "html"}, options));
}

答案 1 :(得分:2)

这不是Backbone设计用于操作的方式,但您可以通过添加适当的parse将内容整理到模型字段中(称之为snippet)模型中的功能:

var Filter = Backbone.Model.extend({
  url: '/filters/',
  parse: function (response) {
    return {
      snippet: $(response)
    }
  }
});

同样,你在这里的Backbone的自然顺序之外,但你现在应该可以使用通常的fetch()get()和{{1管理模型内容的方法。例如,

set()

答案 2 :(得分:2)

在我看来,问题是请求的accept标头包含application/json作为默认值,触发错误。您可以通过model.fetch({ dataType : 'html'})调整接受标头。接受这个问题的答案是:Backbone.js fetch with parameters帮助我找到了答案。

答案 3 :(得分:0)

我认为这个问题的答案是您需要将主干模型的同步方法替换为使用HTML的同步方法。以下代码生成的模型包含“代码段”值中的数据:

sync: function (method, model, options) {
    // NOTE: This generic function won't work for pushing changes
    if (method !== 'read') {
        console.log('Cannot update html model');
        return false;
    }

    // As we're only reading default type to GET - see Backbone.sync
    // for a more generic way of doing this.
    var params = _.extend({ type: 'GET',
        contentType: 'application/xml',
        dataType: 'text'
    });

    var urlError = function () {
        throw new Error('A "url" property or function must be specified');
    };

    // ensure that we have a URL
    if (!params.url) {
        params.url = _.result(model, 'url') || urlError();
    }

    // NOTE: If you extend this function to deal with creates you'll need to ensure
    // params.data is set and make sure that the data isn't processed.
    // See the Backbone.sync methods for more info

    // Finally wrap the backbone success callback to plonk the data in snippet field of an object
    var origSuccess = options.success;
    options.success = function (data, textStatus, xhr) {
        origSuccess({ snippet: data }, textStatus, xhr);
    };

    // Make the request, allowing the user to override any Ajax options.
    var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
    model.trigger('request', model, xhr, options);
    // make the request
    return xhr;
}

标准骨干阅读功能应该遵循这一点。写作将失败,但你总是可以扩展功能来处理这些。

答案 4 :(得分:0)

这个问题有点老了,但是我在git上发现了一个项目,它通过循环遍历项目服务器端并在呈现页面时将它们添加到集合中来描述更新模型的非常好的方法。

https://github.com/runemadsen/Backbone-With-Server-Side-Rendering/blob/master/views/modeltest.erb