2

我想开始使用 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 响应一起使用?或者我根本不应该使用模型?

4

5 回答 5

3

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

fetch: function(options) {
    return Backbone.Model.prototype.fetch.call(this, _.extend({ dataType: "html"}, options));
}
于 2013-07-03T01:05:22.557 回答
2

这并不是 Backbone 设计的真正操作方式,但您可以通过在模型中snippet包含适当的parse函数来将您的内容填充到模型字段(称为它)中:

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

同样,您在这里有点超出 Backbone 的自然顺序,但您现在应该能够使用通常fetch()get()、 和set()方法来管理模型的内容。例如,

// in view:
updateFilter: function (filter) {
    this.$el.html(filter.get('snippet'));
},
// etc..
于 2012-09-08T16:12:07.813 回答
2

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

于 2013-06-25T20:45:51.013 回答
0

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

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

于 2013-10-02T15:39:40.727 回答
0

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

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;
}

标准的主干阅读功能应该在此之后工作。写的会失败,但你总是可以扩展函数来处理这些。

于 2013-04-18T09:55:29.330 回答