为什么更改模型不会同时更改 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。
我有 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。