How to create nested models in Ember.js?

前端 未结 4 1397
感情败类
感情败类 2020-12-24 09:16

Going through Ember.js documentation, I am not able to figure out how to create nested models. Assume that I have the following JSON:

App.jsonObject = {
             


        
相关标签:
4条回答
  • 2020-12-24 09:35

    I wrote my own simple model factory based on Alexandros K's solution but supporting ES6 modules. Thought I would share it :)

    import Ember from 'ember';
    
    var ModelFactory = Ember.Object.extend({});
    
    ModelFactory.reopenClass({
        getType(obj) {
            if(!obj) {
                return null;
            }
    
            if(Array === obj.constructor) {
                return "array";
            }
            else if(typeof obj === "object") {
                return "object";
            }
    
            return null;
        },
    
        // Factory method..
        create: function (arg) {
    
            const _this = this;
    
            switch (this.getType(arg)) {
    
                // Return an Ember Array
                case "array":
    
                    var newArray = [];
    
                    arg.forEach(function(item) {
                        newArray.pushObject(_this.create(item));
                    });
    
                    return newArray;
    
                // Or a recursive object.
                case "object":
    
                    var newObject = Ember.Object.create();
    
                    for (var key in arg) {
                        if (arg.hasOwnProperty(key)) {
                            newObject.set(key, this.create(arg[key]));
                        }
                    }
    
                    return newObject;
    
                default:
    
                    // Or just return the args.
                    return arg;
            }
        }
    });
    
    
    export default ModelFactory;
    

    Usage:

    ModelFactory.create(json)
    
    0 讨论(0)
  • 2020-12-24 09:39

    You need to use pushObject not push when adding to Ember array objects with bindings. And you should probably use get() when accessing the positions property. See my jsFiddle for the corrections.

    http://jsfiddle.net/ud3323/Y5nG5/

    0 讨论(0)
  • 2020-12-24 09:52

    Answer relevant for Ember 2.5.0 / May 2016

    I had a similar question (see below for my case) and was getting frustrated by the numerous out-dated / no-longer-helpful threads so am posting what I learned here in case it is helpful to others who stumble across this page.

    TL;DR: In more recent versions of Ember you define your model by extending the Model object in ember-data with the attributes you want. The attributes are defined by calling DS.attr(type) (where the type parameter can be omitted to pass through whatever types you want, e.g. nested objects from your JSON).

    So for this question you could create app/models/account (possibly by using ember-cli --> ember g resource account):

    import Model from 'ember-data/model';
    import attr from 'ember-data/attr';
    import { hasMany } from 'ember-data/relationships';
    
    export default Model.extend({
        name: attr('string'),
        positions: hasMany('position')
    });
    

    and similarly for app/models/position:

    import Model from 'ember-data/model';
    import attr from 'ember-data/attr';
    
    export default Model.extend({
        symbol: attr('string'),
        quantity: attr('number')
    });
    

    My case:

    I wanted to have a device that is associated with a connection that might be a serial or TCP connection, each with different options/parameters. In plain JS, I would've done something like this:

    [{
        name: "My serial device",
        connection: {
            type: "serial",
            options: {
                port: "COM1",
                baud: 115200,
                data_bits: 8,
                parity: "none",
                stop_bits: 1,
                flow_control: "none"
            }
        }
    }, {
        name: "My TCP/IP device",
        connection: {
            type: "tcp",
            options: {
                host: "127.0.0.1",
                port: 23
            }
        }
    }]
    

    in Ember this translates to a device model with a connection property whose type is an object (left unspecified):

    import Model from 'ember-data/model';
    import attr from 'ember-data/attr';
    
    export default Model.extend({
        name: attr('string'),
        connection: attr()
    });
    

    If you're wondering what is a good criterion for determining whether something should be it's own model (with belongsTo, hasMany, etc. relationship) or not, a simple question to start with is whether or not the resource in question would otherwise have id numbers associated with it. In this case, it doesn't make much sense to track connections and devices separately, so I opted not to create a separate model for connections.

    0 讨论(0)
  • 2020-12-24 09:59

    I've created a recursive object factory that you may like:

    It will iterate over the object and create Ember Arrays or nested objects, returning a full Ember Object tree!

    Here is the source for your reference, and a JS fiddle: http://jsfiddle.net/SEGwy/2/

    Please note: the fiddle writes the output to the console, so you won't see any output on the screen.

      RecursiveObject = {
    
          // http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
          TypeOf: function (input) {
              try {
                  return Object.prototype.toString.call(input).match(/^\[object\s(.*)\]$/)[1].toLowerCase();
              } catch (e) {
                  return typeof input;
              }
          },
    
          // Factory method..
          create: function (args) {
    
              args = args || {};
              ctxt = this;
    
              switch (this.TypeOf(args)) {
    
                  // Return an Ember Array
                  case "array":
    
                      var result = Ember.A();
    
                      for (var i = 0; i < args.length; i++) {
                          x = this.create(args[i]);
                          result.push(x);
                      };
    
                      break;
    
                  // Or a recursive object.
                  case "object":
    
                      var result = Ember.Object.create();
    
                      $.each(args, function (key, value) {
    
                          result.set(key, ctxt.create(value));
    
                      });
    
                      break;
    
                  default:
    
                      // Or just return the args.
                      result = args;
                      break;
    
              }
    
              return result;
    
          }
    
      }
    
      // Example
    
      jsonObject = {
        id: 1812,
        name: 'Brokerage Account',
        positions: [
            {
                symbol: 'AAPL',
                quantity: '300'
            },
            {
                symbol: 'GOOG',
                quantity: '500'
            }
        ]
      }
    
      x = RecursiveObject.create(jsonObject);
      console.log(x);
    
    0 讨论(0)
提交回复
热议问题