8

私はこれを構築しようとしています:
ここに画像の説明を入力

左側のフィールドを編集すると、右側のフィールドが更新され、その逆も同様です。

  • 入力フィールドの値を編集すると、テキスト カーソルがその末尾にジャンプします。

  • スクリーンショットでわかるように、華氏フィールドに「2」と入力すると、1.999999999999 に置き換えられます。これは、
    ビューの Fº → モデルの Cº → ビューの Fº という二重変換が原因で発生します。

反動

どうすればそれを回避できますか?


アップデート:

Backbone.js などの MVC フレームワークで双方向バインディングを処理するエレガントな方法を知りたいです。

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();

MVC なし

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 を間違っています。

4

3 に答える 3

1

2つの方法が思い浮かびます。Kinakuta が述べたように、次のようなことができるので、数学は小数ではなく整数で機能します。

temp = ((oldTemp * 100) * conversion stuff) / 100

アプリの複雑さに応じて、 のようなものを使用することもできますBackbone.ModelBinder。ビューをモデルに自動的にバインドするため、一方が更新されると、もう一方も自動的に更新されます。次に、コンバーター関数をバインディングにアタッチして、値がコンバーターを通過するview -> modelmodel -> view、コンバーターを通過するようにします。そのアイデアに興味があれば、さらに詳しく説明できます。

更新: シンプルな一時コンバーターを使用すると、Backbone に 3.5 倍のコードが必要であることは驚くことではありません。MVC フレームワークは、大規模なプロジェクトの肥大化を抑えることができますが、小さなアプリの場合はやり過ぎかもしれません。たとえば、バックボーンを使用して「Hello World」を表示することを想像してください。

あなたの問題については、両方ではなく、一方が変更されたときに他方の入力値のみをレンダリングするのはどうですか? F 入力が変更された場合、C ボックスの値を再レンダリングします。ModelBinderモデルに と の 2 つの属性を持たせることでこれを行いtempFますtempC。一方が変更されると、もう一方を再計算し、ModelBinder が自動的に表示します。または、MB を使用せずに変更イベントをリッスンすることもできます。

于 2013-04-05T02:53:00.453 に答える