我试图弄清楚如何将模型绑定到文本字段,以便在更新文本字段中的值时,还更新基础模型(并将PUT请求发送到适当的API)。从文档中,ember-data似乎能够做到这一点,但是我无法将自定义文本字段连接到控制器/模型。
以下是我的模型的外观:
AS.Run = DS.Model.extend({
'analyticsPlan' : DS.attr('string'),
'commandScript' : DS.attr('string'),
'parameters' : DS.hasMany('parameter')
});
AS.Parameter = DS.Model.extend({
'name' : DS.attr('string'),
'type' : DS.attr('string'),
'description' : DS.attr('string'),
'value' : DS.attr('string'),
'default' : DS.attr('string'),
'analyticRun' : DS.belongsTo("run")
});
这是我的模板:
<table style="width:100%;" class="affi-table">
<thead>
<tr class="ui-state-default">
<th style="width:120px;">Parameter Type</th>
<th style="width:120px;">Parameter Name</th>
<th>Description</th>
<th>Default value</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{{#each parameter in parameters}}
<tr>
<td>{{parameter.type}}</td>
<td>{{parameter.name}}</td>
<td>{{parameter.description}}</td>
<td>{{parameter.default}}</td>
<td>{{view AS.AnalyticsParameterTextField valueBinding="parameter.value" placeholder="" nameBinding="parameter.name" style="width:200px;"}}</td>
</tr>
{{/each}}
</tbody>
</table>
AnalyticsParameterTextField定义为:
AS.AnalyticsParameterTextField = Ember.TextField.extend({
attributeBindings: ['name','style'],
focusOut: function(evt) {
var paramName = this.get('name');
var paramValue = this.value;
console.log(this.get('controller'));//this returns <AS.AnalyticsParameterTextField:ember568> which is not the controller
//this was working before when I was not using ember model objects, but when I was just pulling the json data right out from a rest end point
}
});
我真的可以帮助找出如何在AnalyticsParameterTextField中获取控制器。一旦整理完毕,我需要弄清楚如何更新底层模型,并提出服务器API请求来更新数据库。我想我可以发出ajax请求来更新底层数据库但是在ember-data版本1中我想我可以在我的控制器中使用这样的东西:
var p = this.get('store').find('parameter',somekey)
p.save();
更新:
我现在使用Ember TextField valueBinding with dynamic property中提供的示例来解决问题 但似乎必须有更好的方法来解决这个问题。
我的模板如下:
{{#each parameter in parameters}}
<tr>
<td>{{parameter.type}}</td>
<td>{{parameter.name}}</td>
<td>{{parameter.description}}</td>
<td>{{parameter.default}}</td>
<td>{{view AS.AnalyticsParameterTextField paramValueBinding="parameterValue" valueBinding="parameter.value" placeholder="" nameBinding="parameter.name" style="width:200px;"}}</td>
</tr>
{{/each}}
文本域代码如下:
AS.AnalyticsParameterTextField = Ember.TextField.extend({
attributeBindings: ['name','style'],
paramValue : {},
updateValues: function() {
var name = this.get('name');
var val = this.value;
this.set('paramValue',{"name":name,"value":val});
}.observes('value')
});
我的控制器看起来像:
AS.AnalyticsConfigController = Ember.ObjectController.extend({
runId : null,
parameterValue : null,
/*
* This function is called every time a parameter is updated/changed.
* It makes API call to appropriate rest end point("/analytics/runs/:runId/parameters/:name" to be specific)
*/
updateRunParameter:function(){
var store = this.get('store');
var runId = this.get('runId');
/*
* defining namespace rule for the "parameter" model here because the namespace depends on the dynamic parameter value "runId"
*/
AS.ParameterAdapter = DS.RESTAdapter.extend({
namespace: AS.baseURL.substr(1)+"analytics/runs/"+runId
});
store.find('parameter', 'historyDir').then(function(parameterObject) {
//once the promise is resolved, save the parameter object
parameterObject.save();
});
}.observes('parameterValue')
});
但我必须说我讨厌这种方法,必须有一种更清洁的方法来做到这一点。现在,当文本字段值更新时,它会更新自己的属性,然后更新控制器属性,然后控制器会监视此属性以进行适当的API调用。
答案 0 :(得分:7)
从指南的“入门”部分说明,您应该使用{{input}}帮助程序而不是自定义视图http://emberjs.com/guides/getting-started/marking-a-model-as-complete-incomplete/)。它应该是这样的:
<td>{{input type="text" value=parameter.value}}</td>
控制器知道哪条记录在哪里,这就是为什么它可以“神奇地”在输入HTML元素和相应记录的值之间建立链接。
现在对于focusOut部分,我将使用td上的{{action}}帮助程序来捕获事件(对于事件类型:http://emberjs.com/guides/templates/actions/#toc_specifying-the-type-of-event读取此内容),如下所示:
<td {{action "focusOut" parameter on="focusOut">{{input type="text" value=parameter.value}}</td>
必须在控制器中设置“focusOut”动作,参数是您发送给函数的模型,而on =“focusOut”是动作响应的事件。 将参数发送到动作“focusOut”的好处是,在控制器的focusOut动作中,您只需调用:
---- controller code ----
focusOut: function(model){
model.save();
}
---- controller code ----
如果您使用的是Ember-Data,商店会知道您的模型和要使用的适配器,因此您只需调用save(它位于Ember-Data API中,位于DS.Model类下)。
由于我现在只使用FIXTURES,我无法真正说出适配器,但你可以看看指南中的模型部分,它可能对你有所帮助。