|
164 | 164 | * primitive - Throw error, primitives cannot be synced
|
165 | 165 | * null - Create blank object and assign id
|
166 | 166 | */
|
167 |
| - Backbone.Firebase._checkId = function(snap) { |
| 167 | + Backbone.Firebase._checkId = function(snap, idAttribute) { |
168 | 168 | var model = snap.val();
|
169 | 169 |
|
170 | 170 | // if the model is a primitive throw an error
|
|
180 | 180 | }
|
181 | 181 |
|
182 | 182 | // set the id to the snapshot's key
|
183 |
| - model.id = Backbone.Firebase._getKey(snap); |
| 183 | + model[idAttribute] = Backbone.Firebase._getKey(snap); |
184 | 184 |
|
185 | 185 | return model;
|
186 | 186 | };
|
|
348 | 348 | }
|
349 | 349 |
|
350 | 350 | },
|
351 |
| - |
| 351 | + |
352 | 352 | sync: function(method, model, options) {
|
353 | 353 | Backbone.Firebase.sync(method, model, options);
|
354 | 354 | },
|
|
359 | 359 | _setId: function(snap) {
|
360 | 360 | // if the item new set the name to the id
|
361 | 361 | if(this.isNew()) {
|
362 |
| - this.set('id', Backbone.Firebase._getKey(snap), { silent: true }); |
| 362 | + this.set(this.idAttribute, Backbone.Firebase._getKey(snap), { silent: true }); |
363 | 363 | }
|
364 | 364 | },
|
365 | 365 |
|
|
376 | 376 | * by comparing the keys that have been removed.
|
377 | 377 | */
|
378 | 378 | _unsetAttributes: function(snap) {
|
379 |
| - var newModel = Backbone.Firebase._checkId(snap); |
| 379 | + var newModel = Backbone.Firebase._checkId(snap, this.idAttribute); |
380 | 380 |
|
381 | 381 | if (typeof newModel === 'object' && newModel !== null) {
|
382 | 382 | var diff = _.difference(_.keys(this.attributes), _.keys(newModel));
|
|
399 | 399 | var modelObj = model.changedAttributes();
|
400 | 400 | _.each(model.changed, function(value, key) {
|
401 | 401 | if (typeof value === 'undefined' || value === null) {
|
402 |
| - if (key == 'id') { |
| 402 | + if (key == model.idAttribute) { |
403 | 403 | delete modelObj[key];
|
404 | 404 | } else {
|
405 | 405 | modelObj[key] = null;
|
|
438 | 438 | * Backbone.Firebase.sync with the correct method.
|
439 | 439 | */
|
440 | 440 | create: function(model, options) {
|
441 |
| - model.id = Backbone.Firebase._getKey(this.firebase.push()); |
| 441 | + // XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute |
| 442 | + model[this.idAttribute] = Backbone.Firebase._getKey(this.firebase.push()); |
442 | 443 | options = _.extend({ autoSync: false }, options);
|
443 | 444 | return Backbone.Collection.prototype.create.call(this, model, options);
|
444 | 445 | },
|
|
448 | 449 | * Backbone.Firebase.sync with the correct method.
|
449 | 450 | */
|
450 | 451 | add: function(model, options) {
|
451 |
| - model.id = Backbone.Firebase._getKey(this.firebase.push()); |
| 452 | + // XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute |
| 453 | + model[this.idAttribute] = Backbone.Firebase._getKey(this.firebase.push()); |
452 | 454 | options = _.extend({ autoSync: false }, options);
|
453 | 455 | return Backbone.Collection.prototype.add.call(this, model, options);
|
454 | 456 | },
|
|
503 | 505 | // Defer the listener incase the data is cached, because
|
504 | 506 | // then the once call would be synchronous
|
505 | 507 | _.defer(_.bind(function() {
|
506 |
| - |
507 | 508 | this.firebase.once('value', function() {
|
508 | 509 | // indicate that the call has been received from the server
|
509 | 510 | // and the data has successfully loaded
|
|
541 | 542 | this._suppressEvent = true;
|
542 | 543 | }
|
543 | 544 |
|
544 |
| - var childRef = this.firebase.ref().child(model.id); |
| 545 | + // XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute |
| 546 | + var childRef = this.firebase.ref().child(model[this.idAttribute]); |
545 | 547 | childRef.set(model, _.bind(options.success, model));
|
546 | 548 | }
|
547 | 549 |
|
|
568 | 570 |
|
569 | 571 | for (var i = 0; i < parsed.length; i++) {
|
570 | 572 | var model = parsed[i];
|
571 |
| - var childRef = this.firebase.child(model.id); |
| 573 | + // XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute |
| 574 | + var childRef = this.firebase.child(model[this.idAttribute]); |
572 | 575 | if (options.silent === true) {
|
573 | 576 | this._suppressEvent = true;
|
574 | 577 | }
|
|
628 | 631 | for (var i = 0; i < models.length; i++) {
|
629 | 632 | var model = models[i];
|
630 | 633 |
|
631 |
| - if (!model.id) { |
632 |
| - model.id = Backbone.Firebase._getKey(this.firebase.push()); |
633 |
| - } |
| 634 | + // XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute |
| 635 | + model[this.idAttribute] = model[this.idAttribute] || Backbone.Firebase._getKey(this.firebase.push()); |
634 | 636 |
|
635 | 637 | // call Backbone's prepareModel to apply options
|
636 | 638 | model = Backbone.Collection.prototype._prepareModel.call(
|
|
649 | 651 | },
|
650 | 652 |
|
651 | 653 | _childAdded: function(snap) {
|
652 |
| - var model = Backbone.Firebase._checkId(snap); |
| 654 | + // XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute |
| 655 | + var model = Backbone.Firebase._checkId(snap, this.idAttribute); |
653 | 656 |
|
654 | 657 | if (this._suppressEvent === true) {
|
655 | 658 | this._suppressEvent = false;
|
656 | 659 | Backbone.Collection.prototype.add.call(this, [model], {silent: true});
|
657 | 660 | } else {
|
658 | 661 | Backbone.Collection.prototype.add.call(this, [model]);
|
659 | 662 | }
|
660 |
| - this.get(model.id)._remoteAttributes = model; |
| 663 | + this.get(model[this.idAttribute])._remoteAttributes = model; |
661 | 664 | },
|
662 | 665 |
|
663 | 666 | // TODO: child_moved is emitted when the priority for a child is changed, so it
|
|
669 | 672 | // when a model has changed remotely find differences between the
|
670 | 673 | // local and remote data and apply them to the local model
|
671 | 674 | _childChanged: function(snap) {
|
672 |
| - var model = Backbone.Firebase._checkId(snap); |
| 675 | + // XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute |
| 676 | + var idAttribute = this.idAttribute; |
| 677 | + var model = Backbone.Firebase._checkId(snap, idAttribute); |
673 | 678 |
|
674 | 679 | var item = _.find(this.models, function(child) {
|
675 |
| - return child.id == model.id; |
| 680 | + return child.id == model[idAttribute]; |
676 | 681 | });
|
677 | 682 |
|
678 | 683 | if (!item) {
|
|
701 | 706 | // remove an item from the collection when removed remotely
|
702 | 707 | // provides the ability to remove siliently
|
703 | 708 | _childRemoved: function(snap) {
|
704 |
| - var model = Backbone.Firebase._checkId(snap); |
| 709 | + // XXX model prototype broken: this.model.prototype.idAttribute worked around as this.idAttribute |
| 710 | + var model = Backbone.Firebase._checkId(snap, this.idAttribute); |
705 | 711 |
|
706 | 712 | if (this._suppressEvent === true) {
|
707 | 713 | this._suppressEvent = false;
|
|
827 | 833 | SyncCollection.apply(this, arguments);
|
828 | 834 | }
|
829 | 835 |
|
| 836 | + // XXX before breaking model prototype: worked around this.model.prototype.idAttribute with this.idAttribute |
| 837 | + this.idAttribute = this.idAttribute || BaseModel.prototype.idAttribute; |
| 838 | + |
| 839 | + // XXX breaking the model prototype |
830 | 840 | // Intercept the given model and give it a firebase ref.
|
831 | 841 | // Have it listen to local changes silently. When attributes
|
832 | 842 | // are unset, the callback will set them to null so that they
|
|
0 commit comments