Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ember Data Filter Objects #23

Closed
wants to merge 3 commits into from
Closed

Conversation

bmac
Copy link
Member

@bmac bmac commented Nov 17, 2014

@knownasilya
Copy link
Contributor

Very interesting idea. I like it a lot, even if it doesn't fix the memory leak.

@igorT igorT mentioned this pull request Dec 2, 2014
28 tasks
@trabus
Copy link

trabus commented Dec 9, 2014

I really like this idea as well, especially if it will help protect against memory leaks. It looks like it could definitely simplify the way we're using store.filter to control when our users load data. We don't use the query param with filter to load any data, but rather we filter already loaded and cached data, only loading data when necessary.

We use store.filter pretty extensively in our app at the model level. We often need to use more than one filter method, and so we built some convenience methods to streamline the process. Our implementation essentially takes an array of objects/functions and converts them into an array of assertions. If all assertions pass, the data makes it through the filter:

// app/utils/data-filter.js
export default function dataFilter(filterData) {
    var filters = filterData.map(function(data) {
        if(typeof data === 'function') {
            return data;
        }
        return assertions[data.type](data.property, data.value);
    });
    return function(obj) {
        var results = filters.map(function(f) {
            return f(obj);
        });
        return results.indexOf(false) === -1;
    };
}

export var assertions = {
    isEqual: isEqual,
    notEqual: notEqual
    ...
// assertion methods 
function isEqual(property, value) {
    return function(obj) {
        return obj.get(property) === value;
    };
}
...

We then have a mixin for the routes that initially loads from a store.find, but uses store.filter on subsequent requests. This lets us control the data into our app better:

// app/mixins/filtered-route.js
export default Ember.Mixin.create({
    isModelLoaded: false,
    modelQuery: null,
    modelFilter: null,

    model: function() {
        return this.setupModel(
            this.get('modelName'), 
            this.get('modelQuery'), 
            this.get('modelFilter')
        );
    },

    setupModel: function(name, query, filters) {
        var filterData = dataFilter(filters);
        var self = this;
        if(!this.get('isModelLoaded') || !this.get('modelFilter')){
            return this.store.find(name, query)
            .then(function(data) {
                self.set('isModelLoaded',true);
                return data;
            });
        } else {
            return this.store.filter(name, filterData);
        }
    }
});

This is a simple, contrived version of our implementation, and doesn't take into account our cached data management or pagination, but I think it gets the point across.

// app/routes/inbox.js
import Ember from 'ember';
import FilteredRoute from 'app/mixins/filtered-route';

export default Ember.Route.extend(FilteredRoute,{
    modelName: 'message',
    modelQuery: { type: 'inbox'},
    modelFilter: function() {
        return [
            {
                type: 'isEqual',
                property:'type',
                value: 'all'
            }
        ];
    }.property()
});

// app/routes/sent.js
import Ember from 'ember';

export default Ember.Route.extend(FilteredRoute,{
    modelName: 'message',
    modelQuery: { type: 'sent'},
    modelFilter: function() {
        return [
            {
                type: 'isEqual',
                property:'type',
                value: 'sent'
            }
        ];
    }.property()
});

I can see filter being a blueprint in Ember-cli. Generating a filter module like you would for an adapter or serializer would be great for separating out your filter logic, and would work well in pods as well. Anyhow, really looking forward to see how this develops.

@stefanpenner
Copy link
Member

@ef4 this actually related to some of our relational language discussions lately.

@mmun mmun added the T-ember-data RFCs that impact the ember-data library label Feb 5, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Response T-ember-data RFCs that impact the ember-data library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants