2013-03-31 3 views
2

Je n'utilise pas les données Ember et j'ai un appel ajax dans mon modèle pour extraire des données d'une source distante. Après avoir reçu avec succès les données de l'API, je veux trier/filtrer en fonction de la catégorie. Mon plan est qu'une fois que je reçois les données du modèle, je peux gérer l'état filtré des données à travers le contrôleur. Mon problème est que parce que l'extraction des données dans le modèle est asynchrone, je ne peux pas appeler exactement une méthode dans mon contrôleur pour filtrer/trier les données à afficher dans le modèle.Ember.js - Gestion des événements et des rappels asynchrones

Les pièces pertinentes de mon code, ci-dessous et dans my jsfiddle. Dans mon modèle itératif sur issue_list je peux facilement afficher les informations. Cependant, je voudrais itérer sur le categorized_issues Array ... et je ne sais pas quand issue_list tableau vraiment est réglé pour que je puisse appeler la méthode categorize de la 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); 
      } 
     }); 
    }, 
}); 

donc mon plan est:

  1. données du modèle Fetch
  2. recatégoriser les données basées sur son statut (ouvert ou fermé) dans le contrôleur.
  3. Afficher ces nouvelles données dans le modèle.

Je peux sembler accomplir ceci. Des idées sur la façon de s'y prendre?

DEBUG: ------------------------------- 
DEBUG: Ember.VERSION : 1.0.0-rc.2 
DEBUG: Handlebars.VERSION : 1.0.0-rc.3 
DEBUG: jQuery.VERSION : 1.9.1 
DEBUG: ------------------------------- 

Répondre

5

Une solution simple serait de déclarer categorize() à titre d'observateur:

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("[email protected]"), 
}); 

Cela signifierait que l'observateur se déclencher à chaque changement de tableau. Ce ne serait probablement pas un problème de performance dans la plupart des cas. Pour vous assurer que categorize est exécuté juste une fois, ce serait encore mieux, si vous utilisez 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('[email protected]'), 

    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); 
      } 
     }); 
    } 
}); 
+0

J'échapperaient complètement le fait que je pouvais observer sur @Chaque aussi. C'était parfait, merci beaucoup! – Rushi