Reputation: 1662
I'm not using Ember Data, and have an ajax call in my Model to pull data from a remote source. After I've successfully received the data from the API, I want to sort/filter it based on category. My plan is that once I get the data from the Model, I can manage the filtered state of the data through the controller.
My problem is that because fetching the data in the Model is asynchronous, i can't exactly call a method in my controller to filter/sort the data to be displayed in the template.
The relevant pieces of my code, below and in my jsfiddle. In my template iterating over issue_list
I can easily display the information. However, I would like to iterate over the categorized_issues
Array ... and I dont know when issue_list
array really gets set so I can call the categorize
method of the IssuesController.
// Default Route for /issues
App.IssuesIndexRoute = Ember.Route.extend({
setupController: function() {
var issues = App.Issue.all(25);
this.controllerFor('issues').processIssues(issues);
}
});
// Model
App.Issue = Ember.Object.extend({});
App.Issue.reopenClass({
// Fetch all issues from the ajax endpoint.
// Won't work on the JS fiddle
all: function() {
var issues = [];
$.ajax({
url: "http://localhost:3000/issues.json",
dataType: 'json',
}).then(function(response) {
response.issues.forEach(function(issue) {
issues.addObject(App.Issue.create(issue));
}, this);
});
return issues;
},
});
// Controller
App.IssuesController = Ember.ArrayController.extend({
issue_list: [],
categorized_issues : {"open":[], "closed": []},
processIssues: function(issues) {
this.set('issue_list', issues);
return issues;
},
categorize: function() {
var self = this;
this.issue_list.forEach(function(i) {
// Based on the issue open or closed status
if (i.status == "open") {
self.categorized_issues["open"].addObject(i);
} else {
self.categorized_issues["closed"].addObject(i);
}
});
},
});
So my plan is:
I can seem to achieve this. Any ideas on how to go about it ?
DEBUG: -------------------------------
DEBUG: Ember.VERSION : 1.0.0-rc.2
DEBUG: Handlebars.VERSION : 1.0.0-rc.3
DEBUG: jQuery.VERSION : 1.9.1
DEBUG: -------------------------------
Upvotes: 2
Views: 1703
Reputation: 11668
An easy solution would be to declare categorize()
as an observer:
App.IssuesController = Ember.ArrayController.extend({
issue_list: [],
categorized_issues : {"open":[], "closed": []},
processIssues: function(issues) {
this.set('issue_list', issues);
return issues;
},
categorize: function() {
var self = this;
// clear the arrays to avoid redundant objects in the arrays
self.get("categorized_issues.open").clear();
self.get("categorized_issues.closed").clear();
this.issue_list.forEach(function(i) {
// Based on the issue open or closed status
if (i.status == "open") {
self.get("categorized_issues.open").addObject(i);
} else {
self.get("categorized_issues.closed").addObject(i);
}
});
}.observes("issue_list.@each"),
});
This would mean that the observer would get triggered on each change of the array. This would be likely no performance problem in most cases. To ensure that categorize
is just run once, it would be even better, if you use Ember.run.once
:
App.IssuesController = Ember.ArrayController.extend({
issue_list: [],
categorized_issues : {"open":[], "closed": []},
processIssues: function(issues) {
this.set('issue_list', issues);
return issues;
},
issueListObserver : function(){
Ember.run.once(this, this.categorize);
}.observes('issue_list.@each'),
categorize: function() {
var self = this;
// clear the arrays to avoid redundant objects in the arrays
self.get("categorized_issues.open").clear();
self.get("categorized_issues.closed").clear();
this.issue_list.forEach(function(i) {
// Based on the issue open or closed status
if (i.status == "open") {
self.get("categorized_issues.open").addObject(i);
} else {
self.get("categorized_issues.closed").addObject(i);
}
});
}
});
Upvotes: 5