Ember get not getting certain attribute

匿名 (未验证) 提交于 2019-12-03 02:31:01

问题:

When running the following from the UserController on Google Chrome, with ember-couchdb-kit-0.9, Ember Data v1.0.0-beta.3-56-g8367aa5, Ember v1.0.0, and this couchdb adapter:

customerSignUp: function () {             var model = this.get('model');             var customer = this.get('store').createRecord('customer', {                 description: 'Why hello sir',                 user: model             });             customer.save().then(function() {                 model.set('customer', customer);                 model.save();             });         } 

with these models:

App.User = App.Person.extend({     name: DS.attr('string'),     customer: DS.belongsTo('customer', {async: true })  App.Customer = DS.Model.extend({     user: DS.belongsTo('user', {async: true}),     description: DS.attr('string') }); 

neither the user nor the customer has their relationship set properly (in the Ember Debugger the user has null and the customer has <computed>, rather than some sort of <EmberPromiseObject> which is what they have when it works). This only happens when the object in question is persisted. If the save() calls are omitted, both have correctly set relationships, but of course the database hasn't been updated with this information. Whenever the saves happen, the relationships are overwritten with empty entries.

I found that the problem was in the adapter's serializeBelongsTo function, which I've now changed my copy to the following:

serializeBelongsTo: function(record, json, relationship) {       console.log("serializeBelongsTo");       console.log(record.get('user'));       console.log(json);       console.log(relationship);       var attribute, belongsTo, key;       attribute = relationship.options.attribute || "id";       console.log(attribute);       key = relationship.key;       console.log(key);       belongsTo = Ember.get(record, key);       console.log(belongsTo);       if (Ember.isNone(belongsTo)) {         return;       }       json[key] = Ember.get(belongsTo, attribute);       console.log(Ember.get(belongsTo, attribute));       console.log(json);       if (relationship.options.polymorphic) {         return json[key + "_type"] = belongsTo.constructor.typeKey;       }       else {         return json;       }     } 

attribute, belongsTo, and key all log as correct, but console.log(Ember.get(belongsTo, attribute)); returns undefined, which I've tried to change to console.log(Ember.get(Ember.get(belongsTo, 'content'), attribute)); since console.log(belongsTo); told me the id attribute was hidden inside a content object. Attached is a screenshot showing what I mean. The change doesn't fix the problem though, and I keep getting undefined. No matter what method I use to try to get the id out of the belongsTo object, I always get either null or undefined. Here are some examples of things I've tried to get content out of the object:

var content = belongsTo.content; var content = Ember.get(belongsTo, 'content'); var content = belongsTo.get('content'); 

console.log(json); returns Object {description: "Why hello sir", user: undefined}

Here's a pastebin showing relevant output: http://pastebin.com/v4mb3PJ2

Update

A very confusing update!

When I save the model from a different function:

saveModel: function() {     this.get('model').save().then(         function( data, textStatus, jqXHR ) {             console.log('Saved successfully.');         },         function( jqXHR, textStatus, errorThrown ) {             console.log(jqXHR);             console.log(errorThrown);             console.log(textStatus);         }     ); } 

The model is correctly saved. Everything in serializeBelongsto works exactly as expected.

Here's a different pastebin showing output for this case: http://pastebin.com/Vawur8Q0

回答1:

I figured out the problem. Basically the belongsTo object in serializeBelongsTo wasn't really resolved by the time it was being referenced, which I found out by querying isFulfilled. So I implemented by saving side this way:

function saveOn (target, attribute) {     target.addObserver(attribute, function () {         if (target.get(attribute)) {             console.log("Inside with %@".fmt(attribute));             target.removeObserver(attribute);             Ember.run.once(target, function() {                 target.save();             });         }     }); };  customerSignUp: function () {     var model = this.get('model');     var customer = this.get('store').createRecord('customer', {         description: 'Why hello sir'     });     customer.save().then(function () {         model.set('customer', customer);         customer.set('user', model);         saveOn(customer, 'user.isFulfilled');         saveOn(model, 'customer.isFulfilled');     }); } 

Now everything works like a charm. It might be a good idea for serializeBelongsTo to take this into account though. This line: console.log(Ember.get(belongsTo, 'isFulfilled')); was coming up false in my case. There was just a race condition of some sort between the creation of the record and it's serialization!

I'd like to make my saveOn function return a promise though, which I could then use to chain multiple saveOns together. That way I wouldn't have to do a customer.save() to make sure the id's were populated.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!