Giter VIP home page Giter VIP logo

Comments (6)

alekseykulikov avatar alekseykulikov commented on July 19, 2024

Hi @asgeo1, thank you for experience. Yes, nested models is a problem for backbone.offline and I will try to create more straightforward solution in next release: #21
Now you can try to play with keys: option, but it's a bit tricky.
Anyway lets make this topic as a starting point for discussions about how to implement nested models to backbone.offline.

from backbone-offline.

johnkron avatar johnkron commented on July 19, 2024

asgeo1 did you resolve this issue some how?

from backbone-offline.

asgeo1 avatar asgeo1 commented on July 19, 2024

@jask24 - not really, I hacked around until I got something working. But it isn't very good and has issues. Backbone.offline is just not designed to work with relational data models in it's current state.

I'm probably going to have to write my own offline solution to work with Backbone-relational in the interim.

from backbone-offline.

ntheile avatar ntheile commented on July 19, 2024

{ cascadeDelete: true } - One to Many

I had a similar issue with one to many relationships and cascading deletes, especially when the parent model was offline. I wrote some helper functions.

Use the { cascadeDelete: true } option when you initialize storage and when you use the the keys option

If the key is used as a foreign key in a one to many relationship on the collection it will automatically
delete the child models. This is used by default only when the parent is dirty because the default behavior assumes your sql server will take care of cascading when online. If your sql server does not take care of cascading you can pass an optional parameter { serverCascades : false} This will delete all child dependent models when the parent is deleted

usage

this.storage = new Offline.Storage("Files", this, { 
        keys: { folderId: folderCollection }, cascadeDelete: true
});

optional usage: if your server does not cascade

this.storage = new Offline.Storage("Files", this, { 
     keys: { folderId: folderCollection }, cascadeDelete: true, serverCascades: false
});

example (for people who speak in code)

One to many relationship with cascade example (One folder to many files)

// Parent
    //Folder Collection
    var FolderCollection = Backbone.Collection.extend({  
        initialize: function (models, options) {
            var self = this;
            self.storage = new Offline.Storage("Folder", self);
        }
    });

    var folderCollection = new FolderCollection({ name: "Folder1"});

 // Child
    //Files Collection
    var FilesCollection = Backbone.Collection.extend({  
        initialize: function (models, options) {
            var self = this;
            self.storage = new Offline.Storage("Files", self, { keys: { folderId: folderCollection }, cascadeDelete: true });
        }
    });

    var fid = folderCollection.models[0].get("id");
    var filesCollection = new FilesCollection([
        { name: "File1", folderId: fid },
        { name: "File2", folderId: fid }
    ]);

// Cascade Delete - destroy the parent folder
    // when a folder is deleted from the FolderCollection there is a listener for the remove event
    // It loops the FileCollection and cascades a deletion on all models that have the folderId as the fk

    folderCollection.models[0].destroy({
        success: function (model, response) {
            // if autoPush is not turned on
            folderCollection.storage.sync.push();
            console.log("cascade complete");
        }
    });

Code to add to backbone.offline source

[... Add to Storage, maybe after this.autoPush = options.autoPush || false; ... ]

// <cascade setup>
this.cascadeDelete = options.cascadeDelete || false; 
if ( this.cascadeDelete == true ) { 

    var parentCollection;
    var cascadeKey;
    var cascadeCollection = this.collection;
    var serverCascades = options.serverCascades || true;

    // loop keys to snag parentCollection and cascadeKey
    var _ref = this.keys;
    for (var field in _ref) {
        parentCollection = _ref[field];
        cascadeKey = field;
    }

    // console.log("parentCollection");
    // console.log(parentCollection);
    // console.log("cascadeKey");
    // console.log(cascadeKey);
    // console.log("cascadeCollection");
    // console.log(cascadeCollection);

    this.cascadeListener(parentCollection, cascadeCollection, cascadeKey, serverCascades);

}
// </ cascade setup >


[... After replaceKeyFields ... ]

///
/// < cascade functions >
/// Added for cascade deletes.
/// Pass in the parentModel that is being deleted.
/// If the model has cascadeDelete options passed it will cascade 
///    deletions down to all dependent child models in the cascadeCollection
///    based on the cascadeKey (this is usually the pk of the parentModel and the fk on the cascadeCollection model)
///    
    Storage.prototype.cascadeListener = function (parentCollection, cascadeCollection, cascadeKey, serverCascades) {
        // bind to this collections remove event so we can cascade deletes down to children
        var self = this;

        parentCollection.on("remove", function (parentModel) {
            console.log("parent model");
            console.log(parentModel);
            self.cascadeOnDelete(parentModel, cascadeCollection, cascadeKey, serverCascades);
        }, self);
    };

    Storage.prototype.cascadeOnDelete = function (parentModel, cascadeCollection, cascadeKey, serverCascades) {

        // when a model from parentCollection is deleted the cascadeOnDelete function is 
        // fired which loops all models in cascadeCollection where cascadeKey equals parentModelId
        // if serverCascades equals false or the parentModel is dirty then the child Models will be deleted
        // The case where the cascade will not occur is if serverCascades = true and the parent model is not dirty, 
        // meaning your sql server will take care of cascading the delteions for you. 

        var parentModelId = parentModel.get("id");
        var dirty = parentModel.get("dirty");

        whereClause = $.parseJSON('{"' + cascadeKey + '":"' + parentModelId + '"}');

        if (dirty == true || serverCascades == false) {
            console.log("whereClause");
            console.log(whereClause);

            _.each(cascadeCollection.where(whereClause), function (childModel) {
                console.log("deleting child model");
                console.log(childModel);
                childModel.destroy();
            });
        }
        else{
            console.log("the server will take of the cascade for you :)");
        }

    };
/// </ end cascade functions >

return Storage;

})();

[...]

from backbone-offline.

reinventit avatar reinventit commented on July 19, 2024

Hi, I'm trying to use this plugin alongside backbone-relational as well, but contrary to asgeo1 I can't seem to make this work for the use case given.

When I fetch my nested models from the server for a collection with offline storage enabled, the 'relations' are not instantiated. I can't figure out why this isn't working, does backbone_offline somehow block the related models from being instantiated? Could this be an issue with my code or is this expected considering that backbone_offline and backbone-relational don't play well together?

Would be really nice if someone could help me out.

from backbone-offline.

asgeo1 avatar asgeo1 commented on July 19, 2024

Hi @reinvanmeeteren, just answering your pm here.

Basically I created a hack to replace backbone-offline. See here: https://gist.github.com/asgeo1/6774805

Wouldn't call it pretty, but it worked for me.

I'm still hoping the nested model support can be added to backbone-offline, as this is a better library then my hack.

But sharing since a couple of people have asked me what my solution was.

from backbone-offline.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.