1

私は2つのフォーム要素を持っています。両方ともbackbone.stickitで双方向データバインドされています。 2番目のフォーム要素(#入力)は、化粧品に過ぎません。(再)レンダリング変更イベントハンドラのバックボーンビューが機能しません

ドロップダウン(#select)メニューのオプションが変更されるたびに、私のビューがレンダリング(再描画)されるという考えがあります。

私は#selectの 'changed'イベントをキャッチして、このビューを(再)レンダリングするthis.render()を呼び出すことでこれを達成しようとしています。

明らかにそれは動作しません。選択したオプションはモデルに保存されません。その理由を理解できません。

私はむしろ、次のコードが動作しない理由を説明、より、ソリューションを探していませんよ。解決策(のように:私のために働く)は、フィドルの一部です - コメントアウト。

HTML:

<script type="text/template" id="tpl"> 
    <h1>Hello <%= select %></h1> 
    <select id="select"> 
    </select> 
    <p>Select: 
    <%= select %> 
    </p> 
    <hr> 
    <input type="text" id="input"> 
    <p>Input: 
    <%= input %> 
    </p> 
</script> 

<div id="ctr"></div> 

はJavaScript:

Foo = Backbone.Model.extend({ 
    defaults: { 
    select: "", 
    input: "", 
    } 
}); 
FooView = Backbone.View.extend({ 
    el: '#ctr', 
    template: _.template($('#tpl').html()), 
    initialize() { 
    this.model.bind('change', function() { 
     console.log("model change:"); 
     console.log(this.model.get('select')); 
     console.log(this.model.get('input')); 
    }, this); 
    //this.model.bind('change:select', function() { this.render(); }, this); // <--------------------- WORKS 
    }, 
    render: function() { 
    this.$el.html(this.template(this.model.toJSON())); 
    this.stickit(); 
    return this; 
    }, 
    events: { 
    'change #select': function(ev) { 
     console.log('change event triggered:'); 
     console.log(this.model.get('select')); 
     console.log(this.model.get('input')); 
     this.render(); // <--------------------- DOES NOT WORK - WHY? 
    }, 
    /* 'click #render': function(ev) { 
     console.log('render event triggered:'); 
     console.log(this.model.get('select')); 
     console.log(this.model.get('input')); 
     this.render(); 
    } */ 
    }, 
    bindings: { 
    '#input': 'input', 
    '#select': { 
     observe: 'select', 
     selectOptions: { 
     collection: function() { 
      return [{ 
      value: '1', 
      label: 'Foo' 
      }, { 
      value: '2', 
      label: 'Bar' 
      }, { 
      value: '3', 
      label: 'Blub' 
      }] 
     } 
     } 
    }, 
    }, 
}); 
new FooView({ 
    model: new Foo() 
}).render(); 

https://jsfiddle.net/r7vL9u07/9/

答えて

1

あなたは、二を破壊しているので、それはあなたのchange #selectイベントハンドラ内からthis.render()を呼び出すために動作しない理由は、 wayが提供しています。このフローは次のようになります。

  • ユーザーは '#select'の値を変更します。
  • change #selectハンドラーが呼び出され、this.render()が呼び出されます。
  • render#ctr新しい選択メニューが選択されていない場合、optionが選択されています。
  • Backbone.stickitは#selectへの変更に応答します。
  • Backbone.stickitは#selectの値を取得しようとしますが、選択されていないoptionが含まれているため、値はundefinedです。
  • Backbone.sticketはmodelselect属性をundefinedに設定します。

Backbone.stickitが正しく、それは機会を得る前に、DOMを変更せずにモデルを更新することができるので、あなたがmodelchange:selectハンドラ内にthis.render()コールを移動した場合、それが動作する理由があります。

+0

ありがとうございます。これを行うには、model.bind( 'change:select')を使用するのが適切な方法です。 – daten

+0

選択が変更されたときに再レンダリングする場合は、「はい」を選択します。 – 76484

+0

ありがとうたくさんの仲間! – daten

関連する問題