我正在尝试构建this:
当我在左侧编辑字段时,它应该更新右侧的字段,反之亦然。
在输入字段中编辑值会导致文本光标在其末尾跳转。
在华氏度字段中键入“2”会被替换为1.999999999999,如屏幕截图所示。这是因为双重转换:
查看Fº→模型的Cº→查看Fº。
我该如何避免?
更新
我想知道在Backbone.js等MVC框架中处理双向绑定的优雅方法。
var Temperature = Backbone.Model.extend({
defaults: {
celsius: 0
},
fahrenheit: function(value) {
if (typeof value == 'undefined') {
return this.c2f(this.get('celsius'));
}
value = parseFloat(value);
this.set('celsius', this.f2c(value));
},
c2f: function(c) {
return 9/5 * c + 32;
},
f2c: function(f) {
return 5/9 * (f - 32);
}
});
var TemperatureView = Backbone.View.extend({
el: document.body,
model: new Temperature(),
events: {
"input #celsius": "updateCelsius",
"input #fahrenheit": "updateFahrenheit"
},
initialize: function() {
this.listenTo(this.model, 'change:celsius', this.render);
this.render();
},
render: function() {
this.$('#celsius').val(this.model.get('celsius'));
this.$('#fahrenheit').val(this.model.fahrenheit());
},
updateCelsius: function(event) {
this.model.set('celsius', event.target.value);
},
updateFahrenheit: function(event) {
this.model.fahrenheit(event.target.value);
}
});
var temperatureView = new TemperatureView();
celsius.oninput = function(e) {
fahrenheit.value = c2f(e.target.value)
}
fahrenheit.oninput = function(e) {
celsius.value = f2c(e.target.value)
}
function c2f(c) {
return 9/5 * parseFloat(c) + 32;
}
function f2c(f) {
return 5/9 * (f - 32);
}
它不仅可以解决问题,还可以减少代码3.5⨉。显然我做的MVC错了。
答案 0 :(得分:5)
这是我对此的看法;而是在交互式视图中呈现每个更改的整个视图,使用视图的jQuery或普通JS上下文,就像非MVC示例一样。
http://jsbin.com/fomugixe/1/edit
正如Backbone文档所说:
避免“双向数据绑定”。虽然它确实是一个漂亮的演示,并且适用于最基本的CRUD,但它在您的真实应用程序中并不是非常有用。有时您希望更新每个按键,有时是模糊,有时是在面板关闭时,有时是在点击“保存”按钮时。
答案 1 :(得分:1)
我想到了两种方法。正如Kinakuta所提到的,你可以做类似下面的事情,所以你的数学是整数而不是小数:
temp = ((oldTemp * 100) * conversion stuff) / 100
根据您希望应用程序的复杂程度,您还可以使用Backbone.ModelBinder
之类的内容。它会自动将您的视图绑定到您的模型,因此当一个更新时,另一个会自动更新。然后,您可以将转换器功能附加到绑定,这样当您的值变为view -> model
或model -> view
时,它将通过转换器运行。如果这个想法让你感兴趣,我可以详细说明。
更新:使用简单的临时转换器,Backbone需要3.5倍的代码并不奇怪。 MVC框架可以减少大型项目中的膨胀,但对于小型应用程序,它可能是过度的。例如想象一下使用Backbone来显示“Hello World”。
至于你的问题,如果只更改一个其他输入值,而不是两者都是如何?如果F输入改变,则在C框中重新渲染值。使用ModelBinder
我会在模型中包含两个属性:tempF
和tempC
。当一个被修改时,我重新计算另一个,ModelBinder自动显示它。或者你可以不用MB而只是听取改变事件。
答案 2 :(得分:0)
在视图级别设置一个变量,其中包含开始转换的输入字段,因此您不会在该字段上调用转换函数。