【问题标题】:Backbone js not populating a model with data using fetch()骨干 js 没有使用 fetch() 用数据填充模型
【发布时间】:2013-03-21 01:04:27
【问题描述】:

我正在使用 Backbone.js 并尝试使用 fetch() 填充我的模型。我遇到的问题是返回的数据没有填充我的模型。我发现了一个类似的问题here。不同之处在于,在我的成功函数内部,我没有看到任何数据更改,也没有触发“更改”事件。

代码:

型号

window.Company = Backbone.Model.extend({
    urlRoot: "/api/company",
    defaults:{
        "id":null,
        "name":"",
        "address":"",
        "city":"",
        "state":"",
        "phone":""
    },
    events: {
        'change': 'doChange'
    },

    doChange: function(event) {
        alert('company changed');
    }
})

路由器

var AppRouter = Backbone.Router.extend({

    routes:{
        "":"home",
        "company/:id":"companyDetails"
    },

    initialize:function () {
        var user = new User();
        this.headerView = new HeaderView({
            model: user
        });
        $('.header').html(this.headerView.el);
        console.log("router initialized.");
    },

    companyDetails: function (id) {
        var company = new Company({
            id: id
        });
        company.fetch({
            success: function(){
                console.log('company.id is ' + company.id);
                console.log('company.name is ' + company.name);
                console.log('company.address is ' + company.address);
                $("#content").html(new CompanyView({
                    model: company
                }).el);
            }
        });
}


});

JSON

{"address":"555 Main St","name":"Confused Technologies","id":"8dc206cc-1524-4623-a6cd-97c185a76392","state":"CO","city":"Denver","zip":"80206","phone":"5551212"}

名称和地址始终未定义。我必须忽略一些简单的东西???

编辑

包括错误地忽略了将模型传递给模板的视图。

查看

window.CompanyView = Backbone.View.extend({

    initialize:function () {
        this.render();
        console.log('CompanyView initialized');
    },

    render:function (eventName) {
        $(this.el).html(this.template());
        return this;
    }

})

【问题讨论】:

  • company.get('name')company.toJSON() 在成功回调中说什么?
  • company.get('name') 似乎返回了名字! toJSON() 返回 [object Object]。这是有前途的!所有这一切的开始是在我的下划线模板中,我有 <%= name =><%= address %> ,它们曾经并且仍然是空的。有什么想法吗?
  • 你平时调用模板函数为html = template(this.model.toJSON()),你是怎么做到的?
  • 这是问题的一部分。我将编辑原始帖子以包含我的观点。我在做$(this.el).html(this.template());。当我在更新成功回调以包含数据参数后将其更改为 $(this.el).html(this.template(this.model.toJSON())); 时,我得到了它的工作。

标签: javascript jquery backbone.js


【解决方案1】:

属性不直接存储在模型上。它们存储在attributes hash 中,因此您可以通过company.attributes 访问它们,尽管company.get(attribute) 是它通常使用的方式。同样,您可以将company.toJSON() 传递给您的模板函数,因为它会返回模型属性的克隆散列。

至于您的更改事件未触发,我假设您的意思是模型事件哈希中的change: doChange。骨干模型实际上并没有对事件哈希做任何事情。这是为了在 Backbone Views 上委派 DOM 事件。我敢打赌,如果您在 fetch 调用之前加上 company.on("change", function (model) { console.log(model.toJSON()); }) 并删除了成功回调,您会在控制台中看到您的模型。

另外,我认为您的$("#content").html... 行不会像您期望的那样工作。我会像这样重写你的路由器回调:

companyDetails: function (id) {
  var company = new CompanyView({
    el: "#content", 
    model: new Company({ id: id })
  });

  // This line would be better in your view's initialize, replacing company with this.
  company.listenTo(company.model, "change", company.render);

  company.model.fetch();
}

CompanyView#render 通常会将this.model.toJSON() 传递给返回html 的模板函数,然后将其传递给this.$el.html()。所以像this.$el.html(this.template(this.model.toJSON()));

【讨论】:

  • 谢谢。这很有帮助。 company.on("change", function (model) { console.log(model.toJSON()); }) 导致我更改成功回调以包含数据参数。
  • 所以这加上我之前更新的视图更改(实际上将this.model.toJSON() 传递给模板)起到了作用。我对事件哈希仍然有些模糊,但我相信只要花一点时间使用主干我就会明白。
  • 另外 +1 用于将 el 传递给构造函数。它更清楚地做了我试图用$("#content").html... 做的事情。
  • Backbone 不会对模型上的事件散列做任何事情。您使用.on.listenTo 为模型事件声明事件处理程序。这通常比成功回调更可取,因为模型可以在 fetch 调用之外更改。在 Backbone Views 中可以找到事件哈希,用于将 DOM 事件(如 click)委托给 View 上的处理程序方法。
【解决方案2】:

好的。据我所知,不更新模型的问题是异步问题。我更新了成功回调以包含数据参数,如下所示:

success: function (data) {
    $('#content').html(new CompanyView({
        model: data
    }).el);
}

请注意,我没有将公司对象作为模型传递,而是原始返回数据。这解决了我的模型问题。

我在评论中提到,这始于我的下划线模板变量 `' 等...为空。我改变了看法:

window.CompanyView = Backbone.View.extend({

    initialize:function () {
        this.render();
        console.log('CompanyView initialized');
    },

    render:function (eventName) {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    }

})

这些东西让我的模型得到了更新,变量也传播到了模板中。

【讨论】:

  • 这似乎不应该工作。当您没有将模型传递给您的视图时,this.model.toJSON() 是如何被调用的? “原始数据”对象没有 toJSON 方法。什么时候调用渲染?
  • 它有效。我是backbone.js 的新手,但我相信分配模型model:data 会对Backbone.Model 对象进行某种转换。 render() 在视图 initialize 函数中被调用。
  • 编辑帖子以包含完整视图而不仅仅是渲染功能。
  • 啊,Backbone.Model 的 fetch 调用了你在模型中传入的成功函数,在设置了属性之后。所以你在success函数中的data变量实际上就是模型。实际响应是成功函数中的第二个参数。来源:backbonejs.org/docs/backbone.html#section-55
  • 啊哈.. 所以它实际上不是原始数据。感谢您的链接。
猜你喜欢
  • 2013-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-14
  • 1970-01-01
  • 2012-02-26
  • 1970-01-01
相关资源
最近更新 更多