Ember model to json

后端 未结 12 1351
北恋
北恋 2020-12-13 13:55

I am looking for an efficient way to translate my Ember object to a json string, to use it in a websocket message below

/*
 * Model
 */

App.node = Ember.Obj         


        
相关标签:
12条回答
  • 2020-12-13 14:50

    App.io.emit('node', {node: node.toJSON()});

    Or if you have an ID property and want to include it:

    App.io.emit('node', {node: node.toJSON({includeId: true})});

    0 讨论(0)
  • 2020-12-13 14:54

    I've written an extensive article on how you can convert ember models into native objects or JSON which may help you or others :)

    http://pixelchild.com.au/post/44614363941/how-to-convert-ember-objects-to-json

    http://byronsalau.com/blog/convert-ember-objects-to-json/

    0 讨论(0)
  • 2020-12-13 14:57

    Here I take @leo, @pangratz and @kevin-pauli solution a little step further. Now it iterates not only with arrays but also through has many relationships, it doesn't check if a value has the type Array but it calls the isArray function defined in Ember's API.

    Coffeescript

    App.Jsonable = Em.Mixin.create
      getJson: ->
        jsonValue = (attr) ->
          return attr.map(jsonValue) if Em.isArray(attr)
          return attr.getJson() if App.Jsonable.detect(attr)
          attr
        base =
          if Em.isNone(@get('jsonProperties'))
            # no list given: let's use all the properties
            this
          else
            # the object has a selective list of properties to inspect
            @getProperties(@get('jsonProperties'))
        hash = {}
        for own key, value of base
          continue if value is 'toString' or Em.typeOf(value) is 'function'
          json[key] = jsonValue(value)
        json
    

    Javascript

    var hasProp = {}.hasOwnProperty;
    
    App.Jsonable = Em.Mixin.create({
      getJson: function() {
        var base, hash, hashValue, key, value;
        jsonValue = function(attr) {
          if (Em.isArray(attr)) {
            return attr.map(jsonValue);
          }
          if (App.Jsonable.detect(attr)) {
            return attr.getJson();
          }
          return attr;
        };
        base = Em.isNone(this.get('jsonProperties')) ? this : this.getProperties(this.get('jsonProperties'));
        json = {};
        for (key in base) {
          if (!hasProp.call(base, key)) continue;
          value = base[key];
          if (value === 'toString' || Em.typeOf(value) === 'function') {
            continue;
          }
          json[key] = jsonValue(value);
        }
        return json;
      }
    });
    
    0 讨论(0)
  • 2020-12-13 14:57

    I have:

    • fixed and simplified code
    • added circular reference prevention
    • added use of get of value
    • removed all of the default properties of an empty component

      //Modified by Shimon Doodkin 
      //Based on answers of: @leo, @pangratz, @kevin-pauli, @Klaus
      //http://stackoverflow.com/questions/8669340
      
      App.Jsonable = Em.Mixin.create({
          getJson : function (keysToSkip, visited) {
              //getJson() called with no arguments,
              // they are to pass on values during recursion.
      
              if (!keysToSkip)
                  keysToSkip = Object.keys(Ember.Component.create());
      
              if (!visited)
                  visited = [];
      
              visited.push(this);
      
              var getIsFunction;
      
              var jsonValue = function (attr, key, obj) {
                  if (Em.isArray(attr))
                      return attr.map(jsonValue);
                  if (App.Jsonable.detect(attr))
                      return attr.getJson(keysToSkip, visited);
                  return getIsFunction?obj.get(key):attr;
              };
      
              var base;
              if (!Em.isNone(this.get('jsonProperties')))
                  base = this.getProperties(this.get('jsonProperties'));
              else
                  base = this;
      
              getIsFunction=Em.typeOf(base.get) === 'function';
      
              var json = {};
      
              var hasProp = Object.prototype.hasOwnProperty;
      
              for (var key in base) {
      
                  if (!hasProp.call(base, key) || keysToSkip.indexOf(key) != -1)
                      continue;
      
                  var value = base[key];
      
                  // there are usual circular references
                  // on keys: ownerView, controller, context === base
      
                  if ( value === base ||
                       value === 'toString' ||
                       Em.typeOf(value) === 'function')
                      continue;
      
                  // optional, works also without this,
                  // the rule above if value === base covers the usual case
                  if (visited.indexOf(value) != -1)
                      continue;
      
                  json[key] = jsonValue(value, key, base);
      
              }
      
              visited.pop();
              return json;
          }
      });
      
      /*
      example:
      
      DeliveryInfoInput = Ember.Object.extend(App.Jsonable,{
       jsonProperties: ["title","value","name"], //Optionally specify properties for json
       title:"",
       value:"",
       input:false,
       textarea:false,
       size:22,
       rows:"",
       name:"",
       hint:""
      })
      */
      
    0 讨论(0)
  • 2020-12-13 14:58

    As stated you can take inspiration from the ember-runtime/lib/core.js#inspect function to get the keys of an object, see http://jsfiddle.net/pangratz666/UUusD/

    App.Jsonable = Ember.Mixin.create({
        getJson: function() {
            var v, ret = [];
            for (var key in this) {
                if (this.hasOwnProperty(key)) {
                    v = this[key];
                    if (v === 'toString') {
                        continue;
                    } // ignore useless items
                    if (Ember.typeOf(v) === 'function') {
                        continue;
                    }
                    ret.push(key);
                }
            }
            return this.getProperties.apply(this, ret);
        }
    });
    

    Note, since commit 1124005 - which is available in ember-latest.js and in the next release - you can pass the ret array directly to getProperties, so the return statement of the getJson function looks like this:

    return this.getProperties(ret);
    
    0 讨论(0)
  • 2020-12-13 15:01

    I modifed @pangratz solution slightly to make it handle nested hierarchies of Jsonables:

    App.Jsonable = Ember.Mixin.create({
        getJson: function() {
            var v, json = {};
            for (var key in this) {
                if (this.hasOwnProperty(key)) {
                    v = this[key];
                    if (v === 'toString') {
                        continue;
                    } 
                    if (Ember.typeOf(v) === 'function') {
                        continue;
                    }
                    if (App.Jsonable.detect(v))
                        v = v.getJson();
                    json[key] = v;
                }
            }
            return json;
        }
    });
    
    0 讨论(0)
提交回复
热议问题