为什么更改模型不会同时更改 EmberJS 中的视图?

Why doesn't changing the Model also change the view in EmberJS?

我有 4 个帖子。每一个都有一个标题和一个作者。现在,它按作者排序。我想单击一个按钮(例如按标题排序)并按标题而不是作者对信息进行排序。

到目前为止,我知道我正在对作者和标题进行排序并且正在更新模型。问题是在视图中显示更新的信息。出于某种原因,我假设如果我只是 this.set('model', newModel) 新信息会自动显示。事实并非如此。

这是我的代码。

practice.hbs

{{outlet}}


<button {{action "sortTitles"}}>Sort by Title</button>
<button {{action "sortAuthors"}}>Sort by Author</button>
{{#each model as |post|}}
    <h2>Title: {{post.title}}</h2>
    <h3>Author: {{post.author}}</h3>
{{/each}}

routes/practice.js

import Ember from 'ember';

export default Ember.Route.extend({
    model() {
        var myArray = [{
            title: "Learning EmberJS",
            author: "Erik Hatchett"
        },{
            title: "Controllers are Dead",
            author: "Frank Treacy"
        },{
            title: "Diddly Doo",
            author: "No I'm Adrian"
        },{
            title: "Yisss",
            author: "Dank Sir"
        }];

        myArray.sort(function(a,b) {
            if (a.author > b.author) {
                console.log(a + " is greater than " + b);
                return 1;
            }
            else {
                console.log(b + " is greater than " + a);
                return -1;
            }
        });

        if ("dat" < "cat") {
            console.log("ayy");
        }

        console.log(myArray[2]);
        return myArray;
    }
});

controllers/practice.js

import Ember from 'ember';

var sortByAuthor = function(a,b) {
            if (a.author > b.author) {
                console.log(a + " is greater than " + b);
                return 1;
            }
            else {
                console.log(b + " is greater than " + a);
                return -1;
            }
        };

var sortByTitle = function(a,b) {
            if (a.title > b.title) {
                console.log(a + " is greater than " + b);
                return 1;
            }
            else {
                console.log(b + " is greater than " + a);
                return -1;
            }
        };



export default Ember.Controller.extend({

    actions: {
        sortAuthors() {
            var myModel = this.get('model');
            console.log(myModel[0].author);
            myModel.sort(sortByAuthor);
            console.log(myModel[0].author);
            this.set('model', myModel);
        },
        sortTitles() {
            var myModel = this.get('model');
            myModel.sort(sortByTitle);
            console.log(myModel[0].title);
            this.set('model', myModel);
        }
    }
});

资料肯定在整理中,模型肯定在更新中。它似乎没有显示排序的信息。

不要在控制器中将模型设置为其他值。这将不起作用,因为这不是在路由和控制器之间设置模型绑定的方式。模型必须由路由管理。

相反,创建一个名为 sortedRows 的控制器 属性,您将从控制器操作中更新它。更新您的模板以循环遍历 sortedRows。

奖励答案

另一个更惯用的解决方案是您可以从控制器操作中设置一个排序键,并将 sortedRows 设置为一个计算 属性,当 sortKey 更改时触发,returns 排序模型。

下面的一些变体应该可以工作(我还没有测试过):

template.hbs

<button {{action (action 'sortBy' 'title')}}>Sort by Title</button>
<button {{action (action 'sortBy' 'author')}}>Sort by Author</button>

{{#each sortedRows as |row|}}
  <h2>Title: {{row.title}}</h2>
  <h3>Author: {{row.author}}</h3>
{{/each}}

controller.js

export default Ember.Controller.extend({
  sortKey: 'author', // or whatever you want the default sort to be
  sortedRows: Ember.computed('sortKey', function() {
    return this.get('model').sortBy(this.get('sortKey'));
  },

  actions: {
    sortBy(sortKey) {
      this.set('sortKey', sortKey);
    }
  }
});

route.js

export default Ember.Route.extend({
  model() {
    return [...];
  }
});

奖金奖金

您可以使用 Ember.computed.sort 进一步简化它,我将把它作为练习留给 reader。