我是Ember的新手,我发现他们的一些概念有点不透明。我有一个管理公司库存的应用程序。有一个屏幕列出了他们的整个库存,并允许他们编辑每个库存项目。默认情况下,文本字段处于停用状态,我想要一个'编辑项目'将disabled / true设置为disabled / false的按钮。我创建了以下正确呈现的内容:
Inv.InventoryitemsRoute = Ember.Route.extend({
model: function(params) {
return Ember.$.getJSON("/arc/v1/api/inventory_items/" + params.location_id);
}
<script type="text/x-handlebars" data-template-name="inventoryitems">
{{#each}}
<div class='row'>
<p>{{input type="text" value=header disabled="true"}}</p>
<p>{{input type="text" value=detail disabled="true"}}</p>
<button {{action "editInventoryItem" data-id=id}}>edit item</button>
<button {{action "saveInventoryItem" data-id=id}}>save item</button>
</div>
{{/each}}
</script>
所以这在UI中渲染很好,但我不知道如何访问特定模型以将文本输入从disabled / true更改为disabled / false。如果我只是像普通的jQuery那样做,我会添加特定模型的id值,并在文本输入中放置一个id,以便我可以设置文本字段。基于阅读文档,似乎我想要一个控制器 - 我想要一个ArrayController用于这个模型实例还是Ember可以自己解决这个问题?
我以为我想做类似以下的事情,但警告身份证给我undefined
:
Inv.InventoryitemsController=Ember.ArrayController.extend({
isEditing: false,
actions: {
editInventoryItem: function(){
var model = this.get('model');
/*
^^^^
should this be a reference to that specific instance of a single model or the list of models provided by the InventoryitemsRoute
*/
alert('you want to edit this:' + model.id); // <-undefined
}
}
});
在Ember文档中,他们使用播放列表示例(此处为:http://emberjs.com/guides/controllers/representing-multiple-models-with-arraycontroller/),如下所示:
App.SongsRoute = Ember.Route.extend({
setupController: function(controller, playlist) {
controller.set('model', playlist.get('songs'));
}
});
但是这个例子有点令人困惑(出于几个原因)但在这个特殊情况下 - 我如何将他们的播放列表概念映射到我试图编辑单个库存项目?
答案 0 :(得分:2)
<script type="text/x-handlebars" data-template-name="inventoryitems">
{{#each}}
<div class='row'>
<p>{{input type="text" value=header disabled="true"}}</p>
<p>{{input type="text" value=detail disabled="true"}}</p>
<button {{action "editInventoryItem" this}}>edit item</button>
<button {{action "saveInventoryItem" this}}>save item</button>
</div>
{{/each}}
</script>
和
actions: {
editInventoryItem: function(object){
alert('you want to edit this:' + object.id);
}
}
你需要什么。但让我更详细地解释一下:
首先,术语:您的“模型”是绑定到控制器的整个对象。当您对阵列控制器中的操作调用this.get('model')
时,您将收到整个模型,在这种情况下是一系列库存项目。
{{#each}}
把手标签迭代选定的数组(默认情况下,它将整个模型用作所选数组)。在{{#each}}
块帮助器中,您可以通过说this
来引用当前所在的特定对象。您也可以通过键入this
来命名迭代对象,而不是依赖于{{#each thing in model}}
声明,其中每个对象都将被引用为thing
。
最后,您的行为能够接受输入。您只需在操作名称后面提供变量名称即可声明这些输入。上面,我使用{{action "saveInventoryItem" this}}
演示了这一点,它会将this
传递给动作saveInventoryItem
。您还需要为该操作添加输入参数,以便接受它。
答案 1 :(得分:1)
好的,那是因为正如你所说,你刚刚开始使用Ember。我可能会这样做:
<script type="text/x-handlebars" data-template-name="inventoryitems">
{{#each}}
<div class='row'>
<p>{{input type="text" value=header disabled=headerEnabled}}</p>
<p>{{input type="text" value=detail disabled=detailEnabled}}</p>
<button {{action "editInventoryItem"}}>edit item</button>
<button {{action "saveInventoryItem"}}>save item</button>
</div>
{{/each}}
</script>
有了这个,你需要在InventoryitemController中定义一个headerEnabled属性(注意它是单数的,而不是包含所有项的那个),而对于detailEnabled和动作,你也可以在相同的控制器或路线:
App.InventoryitemController = Ember.ObjectController.extend({
headerEnabled: false,
detailEnabled: false,
actions: {
editInventoryItem: function() {
this.set('headerEnabled', true);
this.set('detailEnabled', true);
}
}
});
这只是一个如何访问数据的示例,如果相同的属性将启用两个文本字段,那么您只需要一个,而不是我放的两个。如果'each'循环没有选择正确的控制器,只需指定itemController。