Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
272 views
in Technique[技术] by (71.8m points)

javascript - Backbone model .toJSON() doesn't render all attributes to JSON

I need to render a model's attributes to JSON so I can pass them into a template. Here is what a render() function for a view looks like:

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

Here is the attributes output after doing console.log(this.model):

created_at: "2012-04-19"
id: "29"
name: "item"
resource_uri: "/api/v1/item/29/"
updated_at: "2012-04-21"
user: "/api/v1/user/9/"

Here is the model's JSON output after doing console.log(this.model.toJSON()):

id: "29"
__proto__: Object

What happened?

Edit: Here is the instantiation:

  var goal = new Goal({id: id});
  goal.fetch();
  var goalFullView = new GoalFullView({
    model: goal,
  });

Here are the contents of the new view:

  console.log(this.model.attributes);
  console.log(this.model.toJSON());

Here is what the console says:

Object
created_at: "2012-04-23"
id: "32"
name: "test"
resource_uri: "/api/v1/goal/32/"
updated_at: "2012-04-23"
user: "/api/v1/user/9/"
__proto__: Object

Object
id: "32"
name: "test"
__proto__: Object

If the toJSON is supposed to make a clone of the attributes, why doesn't it copy the correct name or why doesn't it copy the created_at, updated_at fields?

Edit 2: Here is the model:

  var Goal = Backbone.Model.extend({

    // Default attributes for Goal
    defaults: {
      name: "empty goal",
    },

    // Check that the user entered a goal
    validate: function(attrs) {
      if (!attrs.name) {
        return "name is blank";
      }
    },

    // Do HTTP requests on this endpoint
    url: function() {
      if (this.isNew()) {
        return API_URL + "goal/" + this.get("id") + FORMAT_JSON;
      }
      return API_URL + "goal/" + FORMAT_JSON;
      //API_URL + "goal" + FORMAT_JSON, 
    },
  });

Edit 3: I figured out that I need to use the success callback from fetch to render a view that uses the model:

goal.fetch({success: function(model) { var goalFullView = new GoalFullView({ model: goal, }); }});

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The toJSON() method just returns a shallow clone of the model's attributes property.

From the annotated Backbone.js source:

toJSON: function(options) {
  return _.clone(this.attributes);
}

Without seeing more of your code, it looks like you directly set properties on the model object, rather than using the set function to set model attributes.

I.e. don't do this:

model.name = "item";

do this:

model.set("name", "item");

EDIT:

For your specific issue, it's possible that you called toJSON before the model had finished loading from the server.

E.g. This won't always work as expected:

var model = new Goal({id: 123});
model.fetch();
console.log(model.toJSON());

But this will:

var model = new Goal({id: 123});
model.fetch({
  success: function() {
    console.log(model.toJSON());
  }
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...