我一直在使用Ember Data,正在进行规范化过程,以便侧载数据here, by Jeremy Gillick。这个过程对我来说是新的,所以我试图在使用我目前从API返回的一些数据时逐步完成示例。
我收到错误,不确定导致错误的原因。错误说Error while processing route: index Cannot read property 'length' of undefined TypeError.
为什么我会收到此错误?
以下是我的代码的小提琴:http://jsfiddle.net/dedy5szu/
这是JS:
App = Ember.Application.create();
/***
MOCK SERVER DATA
***/
var JSON_DATA = {
"pagingInfo": {
"start": 0,
"count": 20
},
"list": [
{
"path": "/path/to/page",
"created": "2014-11-18T21:11:10+0000",
"author": "Luke Skywalker",
"title": "Star Wars",
"items": {}
}
]
};
/***
MODELS
***/
App.Page = DS.Model.extend({
pagingInfo: DS.belongsTo('Info'),
list: DS.hasMany('List')
});
App.Info = DS.Model.extend({
start: DS.attr('number'),
count: DS.attr('number')
});
App.List = DS.Model.extend({
path: DS.attr('string'),
created: DS.attr('string'),
author: DS.attr('string'),
title: DS.attr('string'),
items: DS.attr()
});
/**
Deserialize nested JSON payload into a flat object
with sideloaded relationships.
*/
App.NestedSerializer = DS.RESTSerializer.extend({
/**
Generate a unique ID for a record hash
@param {DS.Store} store
@param {DS.Model} type
@param {Object} hash The record hash object
@return {String} The new ID
*/
generateID: function(store, type, hash){
var id, primaryKey,
serializer = store.serializerFor(type);
type._generatedIds = type._generatedIds || 0;
// Get the ID property name
primaryKey = Ember.get(serializer, 'primaryKey') || 'id';
id = hash[primaryKey];
// Generate ID
if (!id) {
id = 'gen-'+ type.typeKey +'-'+ (++type._generatedIds);
hash[primaryKey] = id;
}
return id;
},
/**
Sideload a record hash to the payload
@method sideloadRecord
@param {DS.Store} store
@param {DS.Model} type
@param {Object} payload The entire payload
@param {Object} hash The record hash object
@return {Object} The ID of the record(s) sideloaded
*/
sideloadRecord: function(store, type, payload, hash) {
var id, sideLoadkey, sideloadArr, serializer;
// If hash is an array, sideload each item in the array
if (hash instanceof Array) {
id = [];
hash.forEach(function(item, i){
id[i] = this.sideloadRecord(store, type, payload, item);
}, this);
}
// Sideload record
else if (typeof hash === 'object') {
sideLoadkey = type.typeKey.pluralize(); // Sideloaded keys are plural
sideloadArr = payload[sideLoadkey] || []; // Get/create sideload array
id = this.generateID(store, type, hash);
// Sideload, if it's not already sideloaded
if (sideloadArr.findBy('id', id) === undefined){
sideloadArr.push(hash);
payload[sideLoadkey] = sideloadArr;
}
}
// Assume it's already pointing to a sideloaded ID
else {
id = hash;
}
return id;
},
/**
Process nested relationships on a single hash record
@method extractRelationships
@param {DS.Store} store
@param {DS.Model} type
@param {Object} payload The entire payload
@param {Object} hash The hash for the record being processed
@return {Object} The updated hash object
*/
processRelationships: function(store, type, payload, hash) {
// If hash is an array, process each item in the array
if (hash instanceof Array) {
hash.forEach(function(item, i){
hash[i] = this.processRelationships(store, type, payload, item);
}, this);
}
else {
// Find all relationships in this model
type.eachRelationship(function(key, relationship) {
var related = hash[key], // The hash for this relationship
relType = relationship.type; // The model type
this.generateID(store, type, hash);
hash[key] = this.sideloadRecord(store, relType, payload, related);
this.processRelationships(store, relType, payload, related);
}, this);
}
return hash;
},
/**
(overloaded method)
Starts the deserialized of all payloads.
@method normalizePayload
@param {Object} payload
@return {Object} the normalized payload
*/
extract: function(store, type, payload, id, requestType) {
var rootKeys = Ember.keys(payload);
// Loop through root properties and process extract their relationships
rootKeys.forEach(function(key){
var type = store.container.lookupFactory('model:' + key.singularize()),
hash = payload[key];
// If the key resolves to a model type, sideload any embedded relationships
if (type) {
this.processRelationships(store, type, payload, hash);
}
}, this);
console.log(payload);
return this._super(store, type, payload, id, requestType);
}
});
App.ApplicationSerializer = App.NestedSerializer;
/***
MOCK ADAPTER
***/
App.PageAdapter = DS.RESTAdapter.extend({
findAll: function(store, type, sinceToken) {
return Ember.RSVP.resolve(JSON_DATA);
}
});
/**
Index route
*/
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.store.find('page');
}
});
以下是模板:
<script type="text/x-handlebars">
<h2> Welcome to Ember.js</h2>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="index">
Index Template!!!
</script>