2

我没有使用 Ember Data,并且在我的模型中有一个 ajax 调用来从远程源中提取数据。从 API 成功接收数据后,我想根据类别对其进行排序/过滤。我的计划是,一旦我从 Model 中得到数据,我就可以通过控制器来管理数据的过滤状态。

我的问题是,因为在模型中获取数据是异步的,所以我不能完全调用控制器中的方法来过滤/排序要在模板中显示的数据。

我的代码的相关部分,在下面和我的 jsfiddle中。在我的模板迭代中,issue_list我可以轻松地显示信息。但是,我想遍历categorized_issues数组......而且我不知道issue_list数组何时真正设置,所以我可以调用categorizeIssuesController 的方法。

// 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);
            }
        });
    },
});

所以我的计划是:

  1. 从模型中获取数据
  2. 根据数据在控制器中的状态(打开或关闭)重新分类数据。
  3. 在模板中显示此新数据。

我似乎可以做到这一点。关于如何去做的任何想法?

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

1 回答 1

5

一个简单的解决方案是声明categorize()为观察者

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"),
});

这意味着观察者会在数组的每次更改时被触发。在大多数情况下,这可能不会出现性能问题。为了确保categorize只运行一次,如果你使用它会更好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);
            }
        });
    }
});
于 2013-04-01T19:30:02.007 回答