diff --git a/backbone.nest.js b/backbone.nest.js index b1db581..cf4eef1 100644 --- a/backbone.nest.js +++ b/backbone.nest.js @@ -10,19 +10,21 @@ //then recursively call toJSON on models within. toJSON: function() { var attr = this.attributes, - resp = _.clone(attr); + resp = _.clone(attr), + nests = this.nests.split(" "), + i, j; //Optimize if we know there is only one nested //collection and we know the name of it. - if(this.nest) { - resp[this.nest] = resp[this.nest].toJSON(); + if(nests.length === 1) { + resp[this.nests] = resp[this.nests].toJSON(); return resp; - } + } else //Optimize if there are multiple and we know the names. if(this.nests) { - var i, j, nests = this.nests.split(" "); for(i = 0, j = nests.length; i < j; i++) { resp[nests[i]] = resp[nests[i]].toJSON(); } + return resp; } //If not loop through all. for(prop in attr) { @@ -32,19 +34,45 @@ }; return resp; }, + //parse + //----- + //This creates a collection if model is passed an array + //under the nest attributes name + parse: function(data) { + var i, j, nests = this.nests.split(" "); + if(nests.length === 1) { + data[this.nests] = new this.nest(data[this.nests]); + } else + if(this.nests) { + for(i = 0, j = nests.length; i < j; i++) { + data[nests[i]] = new this.nest(data[nests[i]]); + } + } + return data; + }, //listenToCollection //------------------ //This bubbles change events from nested collections //up to the container model, not auto to optimize for //standard models. listenToCollection: function() { + var i, j, nests = this.nests.split(" "); var attr = this.attributes; //Optimize if nested collection is explictly known. - if(this.nest) { - return this.listenTo(attr[this.nest], "change", function() { - this.trigger("change change:"+this.nest); + if(nests.length === 1) { + return this.listenTo(attr[this.nests], "change", function() { + this.trigger("change change:"+this.nests); }, this); - }; + } else + //Optimize for multiple and known. + if(this.nests) { + for(i = 0, j = nests.length; i < j; i++) { + this.listenTo(attr[nests[i]], "change", function() { + this.trigger("change change:"+nests[i]); + }, this); + } + return; + } //If not loop through all. for(prop in attr) { if(attr[prop] instanceof Backbone.Collection) { @@ -55,4 +83,26 @@ }; } }); + //Proxy collection methods on nest via the model. + //----------------------------------------------- + + //List all methods we want to proxy + var methods = ['push', 'pop', 'unshift', 'shift']; + + //Go through each one, have it invoke upon the nest + _.each(methods, function(method) { + Backbone.Model.prototype[method] = function() { + var args = Array.prototype.slice.call(arguments), + nests = this.nests.split(" "), i, j; + if(nest.length === 1) { + return Backbone.Collection.prototype[method].apply(this.attributes[this.nests], args); + } + return function(){ + for(i = 0, j = nests.length; i < j; i++){ + Backbone.Collection.prototype[method].apply(this.attributes[nests[i]], args); + }; + }; + }; + }); + }(Backbone)) diff --git a/docs/backbone.nest.html b/docs/backbone.nest.html index e8bed15..0981e1d 100644 --- a/docs/backbone.nest.html +++ b/docs/backbone.nest.html @@ -88,9 +88,11 @@

toJSON

-
      toJSON: function(collection) {
+            
      toJSON: function() {
         var attr = this.attributes,
-            resp = _.clone(attr);
+ resp = _.clone(attr), + nests = this.nests.split(" "), + i, j;
@@ -106,10 +108,10 @@

toJSON

-
        if(collection) {
-          resp[collection] = resp[collection].toJSON();
+            
        if(nests.length === 1) {
+          resp[this.nests] = resp[this.nests].toJSON();
           return resp;
-        }
+ } else
@@ -120,6 +122,26 @@

toJSON

+

Optimize if there are multiple and we know the names.

+ + + +
        if(this.nests) {
+          for(i = 0, j = nests.length; i < j; i++) {
+            resp[nests[i]] = resp[nests[i]].toJSON();
+          }
+          return resp;
+        }
+ + + + +
  • +
    + +
    + +

    If not loop through all.

    @@ -135,11 +157,51 @@

    toJSON

  • -
  • +
  • - + +
    +

    parse

    + +
    + +
  • + + +
  • +
    + +
    + +
    +

    This creates a collection if model is passed an array +under the nest attributes name

    + +
    + +
          parse: function(data) {
    +        var i, j, nests = this.nests.split(" ");
    +        if(nests.length === 1) {
    +          data[this.nests] = new this.nest(data[this.nests]);    
    +        } else
    +        if(this.nests) {
    +          for(i = 0, j = nests.length; i < j; i++) {
    +            data[nests[i]] = new this.nest(data[nests[i]]);
    +          } 
    +        }
    +        return data;
    +      },
    + +
  • + + +
  • +
    + +
    +

    listenToCollection

    @@ -148,11 +210,11 @@

    listenToCollection

  • -
  • +
  • - +

    This bubbles change events from nested collections up to the container model, not auto to optimize for @@ -160,36 +222,59 @@

    listenToCollection

    -
          listenToCollection: function(prop) {
    +            
          listenToCollection: function() {
    +        var i, j, nests = this.nests.split(" ");
             var attr = this.attributes;
  • -
  • +
  • - +
    -

    Optimize if nested collection is explictly named.

    +

    Optimize if nested collection is explictly known.

    -
            if(prop) {
    -            return this.listenTo(attr[prop], "change", function() {
    -              this.trigger("change change:"+prop);
    +            
            if(nests.length === 1) {
    +            return this.listenTo(attr[this.nests], "change", function() {
    +              this.trigger("change change:"+this.nests);
                 }, this);
    -        };
    + } else
  • -
  • +
  • - + +
    +

    Optimize for multiple and known.

    + +
    + +
            if(this.nests) {
    +          for(i = 0, j = nests.length; i < j; i++) {
    +            this.listenTo(attr[nests[i]], "change", function() {
    +              this.trigger("change change:"+nests[i]);
    +            }, this);
    +          } 
    +          return;
    +        }
    + +
  • + + +
  • +
    + +
    +

    If not loop through all.

    @@ -203,7 +288,56 @@

    listenToCollection

    }; }; } - }); + });
    + +
  • + + +
  • +
    + +
    + +
    +

    Proxy collection methods on nest via the model.

    + +
    + +
  • + + +
  • +
    + +
    + +
    +

    List all methods we want to proxy

    + +
    + +
      var methods = ['push', 'pop', 'unshift', 'shift'];
    + +
  • + + +
  • +
    + +
    + +
    +

    Go through each one, have it invoke upon the nest

    + +
    + +
      _.each(methods, function(method) {
    +    Backbone.Model.prototype[method] = function() {
    +      var args = Array.prototype.slice.call(arguments);
    +      return Backbone.Collection.prototype[method].apply(this.attributes[this.nest], args);
    +    }
    +  });
    +
     }(Backbone))
  • diff --git a/tests/console.test.js b/tests/console.test.js index 2e8b9ad..6651b4f 100644 --- a/tests/console.test.js +++ b/tests/console.test.js @@ -1,5 +1,5 @@ -var TestCollection = new Backbone.Collection([ +var testcollection = new Backbone.Collection([ { name:"test1", type:"model" @@ -9,11 +9,13 @@ var TestCollection = new Backbone.Collection([ type:"model" } ]), - TestModel = new Backbone.Model({ - name:"master 1", - type:"master model", - test:TestCollection - }); + TestModel = Backbone.Model.extend({ + nest: "Coll" + }), + testmodel = new TestModel({ + Coll: testcollection, + name:"base" + }) TestModel.on("change", function (change) { console.log("TestModel::change:"); @@ -22,5 +24,7 @@ TestCollection.on("change", function (change) { console.log("TestCollection::change") }); -var mod = TestModel, - col = TestCollection; +var mod = testmodel, + col = testcollection; + +