对于我的实习,我正在制作一个简单的Ember应用程序,在其中我让用户输入要设置为抽认卡标题和抽认卡定义的文本。这些全部作为列表呈现在网页上。
当我为抽认卡输入新标题时,它将更新占位符标题。但是,当我为定义执行此操作时,出现以下错误:
Uncaught Error: Assertion Failed: Cannot call set with 'definition'
on an undefined object.
我希望通过setCardDefToNewDef操作来更新模型中显示的现有定义中的定义。它应该使用id来查找元素。
// app/controllers/about.js
init() {
this._super(...arguments);
this.set('stashedNewTitlesById', {});
this.set('stashedNewDefById', {});
},
addTitle: false,
addDef: false,
actions: {
stashNewTitle(id, value) {
this.stashedNewTitlesById[id] = value;
},
stashNewDef(idDef, valueDef){
this.stashedNewDefById[idDef] = valueDef;
},
setCardTitleToNewTitle(id) {
let card = this.model.find(card => id === card.id);
let newTitle = this.stashedNewTitlesById[id]
set(card, 'title', newTitle);
let element = document.getElementById('input-card-new-title-' + id);
element.value = '';
},
setCardDefToNewDef(idDef){
let cardDef = this.model.find(cardDef => idDef === cardDef.id);
let newDef = this.stashedNewDefById[idDef]
set(cardDef, 'definition', newDef);
let element = document.getElementById('input-card-new-def-' + idDef);
element.valueDef = '';
},
// app/routes/about.js
export default Route.extend({
model() {
return [{
id: 1,
title: 'What is a route',
definition: 'a different page on your website'
}, {
id: 2,
title: 'use _super()',
definition: 'Overriding parent class methods'
}, {
id: 4,
title: 'What is .hbs?',
definition: 'Handlebards file extension'
}];
}
});
// app/templates/about.hbs
<ul>
{{#each this.model as |card index|}}
<div class="">
current title: {{card.title}}
<div class="">
new title:
<br>
<input
id={{concat "input-card-new-title-" card.id}}
type="text"
onchange={{action
(action "stashNewTitle" card.id)
value="target.value"
}}
/>
<button {{action "setCardTitleToNewTitle" card.id}}>
update title
</button>
<br>
current definition: {{card.definition}}
<br>
new definition:
<br>
<input
id={{concat "input-card-new-def-" cardDef.id}}
type="text"
onchange ={{action
(action "stashNewDef" cardDef.id)
valueDef="target.valueDef"
}}
/>
<button {{action "setCardDefToNewDef" cardDef.id}} >
update definition
</button>
</div>
</div>
{{/each}}
</ul>
答案 0 :(得分:1)
Ola Ericka?谢谢您的提问!另外,感谢您提供源代码,我能够在本地重新创建您的问题并找到了问题?
因此,我将首先显示代码,然后再进行一些解释。首先,我没有更改您的路由文件,因此暂时将其忽略。
这里是控制器:
import Controller from '@ember/controller';
import { set } from '@ember/object';
export default Controller.extend({
init() {
this._super(...arguments);
this.set('stashedNewTitlesById', {});
this.set('stashedNewDefById', {});
},
addTitle: false,
addDef: false,
actions: {
stashNewTitle(id, value) {
this.stashedNewTitlesById[id] = value;
},
stashNewDef(idDef, value) {
this.stashedNewDefById[idDef] = value;
},
setCardTitleToNewTitle(id) {
let card = this.model.find(card => id === card.id);
let newTitle = this.stashedNewTitlesById[id]
set(card, 'title', newTitle);
let element = document.getElementById('input-card-new-title-' + id);
element.value = '';
},
setCardDefToNewDef(id) {
let cardDef = this.model.find(card => id === card.id);
let newDef = this.stashedNewDefById[id]
set(cardDef, 'definition', newDef);
let element = document.getElementById('input-card-new-def-' + id);
element.valueDef = '';
},
}
});
这是更新的模板:
<ul>
{{#each this.model as |card index|}}
<div class="">
current title: {{card.title}}
<div class="">
new title:
<br>
<input
id={{concat "input-card-new-title-" card.id}}
type="text"
onchange={{action
(action "stashNewTitle" card.id)
value="target.value"
}}
/>
<button {{action "setCardTitleToNewTitle" card.id}}>
update title
</button>
<br>
current definition: {{card.definition}}
<br>
new definition:
<br>
<input
id={{concat "input-card-new-def-" card.id}}
type="text"
onchange={{action
(action "stashNewDef" card.id)
value="target.value"
}}
/>
<button {{action "setCardDefToNewDef" card.id}} >
update definition
</button>
</div>
</div>
{{/each}}
</ul>
您将注意到的主要区别是,我为card重用了相同的变量名(而不是cardDef),只是为了保持代码一致而不使自己感到困惑?在这种情况下,这实际上引起了问题,因为您正在设置valueDef="target.valueDef"
,但实际上无法使用。您需要将其设置为value="target.value"
,因为这是DOM API所期望的(实际上与Ember无关)。
您可能会注意到代码和我的代码之间还有一些其他差异,但它们可能只是格式上的差异。让我知道您是否还有其他疑问。
现在我们已经解决了严重问题,我想知道您在这里想要实现什么? this所有这些“ stashedNewTitlesById”只是一种阻止您动态更新原始模型的方法吗?如果是这样,那么可能会有一种更简单的方法来进行处理?我很高兴对其进行详细介绍,但是由于我已经回答了您的问题,因此我不确定这是否是正确的论坛……您是否加入了Ember Community Discord了吗?如果您在那里与我联系,我的昵称是@real_ate,我可以帮助您改善此代码示例。