使用Ember数据标准化JSON

时间:2014-11-20 01:19:18

标签: javascript jquery json ember.js ember-data

我一直在使用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>

0 个答案:

没有答案