13

I'm developing a jQuery Backbone.js web application.
As it is in Adobe Flex, I have implemented 2 way data binding in my app for input elements/widgets. So, every input element/widget knows its corresponding model and model attribute name.
When the user hits tab or enter, the field value is automatically given to the model.

container.model.set(this.attrName, this.value, options); // command 1

In the other direction, when the model gets updated from the backend, the view of the input element/widget should automatically get updated:

container.model.bind("change:"+ this.attrName, this.updateView, this); // command 2

The problem is:
When the user hits enter and the model is automatically updated, also the "change:abc" is triggered and this.updateView is called, not only when a new model comes from the backend.

My solution until now was to pass an option "source: gui" when setting the model value when the user pressed enter (command 1), and to check for that in my updateView method. But I am not content with this solution anymore.

Does anybody have a better solution? Thanks alot in advance
Wolfgang

Update:
When the option silent: true is passed, the validate method of the model is not called, so that does not help. See Backbone.js source 0.9.2:

_validate: function(attrs, options) {
  if (options.silent || !this.validate) return true;
4

4 に答える 4

8

Backbone.jsサイトから:

{silent:true}がオプションとして渡されない限り、「変更」イベントがトリガーされます

options.silent = true;
container.model.set(this.attrName, this.value, options);

更新: あなたはあなたの質問に新しいコメントを追加したので、あなたが言及した新しいユースケース(検証フロー)を修正するために私の答えを補足しました:

var ExtendedModel = Backbone.Model.extend({
    uiChange : false,
    uiSet: function (attributes, options, optional) {
        this.uiChange = true;
        this.set(attributes, options, optional);
        this.uiChange = false;
    }
});

var MyModel = ExtendedModel.extend({
});

var model = new MyModel();
model.on('change:name', function(){
  console.log('this.uiChange: ', this.uiChange);
});

//simulates the server side set
model.set({name:'hello'});

//simulates the ui side set you must use it to set from UI
model.uiSet({name:'hello2'});
于 2012-09-26T15:29:02.583 に答える
6

双方向バインディングとは、次のことを意味します。

  1. モデルのプロパティが更新されると、UI も更新されます。
  2. UI 要素が更新されると、変更がモデルに反映されます。

バックボーンには 2 オプションの「組み込み」実装がありません (ただし、イベント リスナーを使用して確実に実装できます)。

Backbone では、ビューの「render」メソッドをそのモデルの「change」イベントにバインドすることで、オプション 1 を簡単に実現できます。オプション 2 を実現するには、入力要素に変更リスナーを追加し、ハンドラーで model.set を呼び出す必要もあります。

(jsfiddle.net/sunnysm/Xm5eH/16) バックボーンに双方向バインディングが設定された jsfiddle の例を確認してください。

于 2015-09-05T12:31:37.860 に答える
2

Backbone.ModelBinderプラグインは、バックボーン ビューとモデル間の双方向データ バインディングを提供するのに最適です。このプラグインのいくつかの重要な機能をカバーするブログ記事を書きました。ここに直接リンクがあります: http://niki4810.github.io/blog/2013/03/02/new-post/

于 2013-04-07T21:45:12.300 に答える