ほとんどのガイドが示すように、モデルが変更されたときに再描画にバインドする単純なビューがあります。
this.model.bind('change', this.render, this);
このビューには、入力ボックスと送信ボタンのあるフォームがあります。モデルの関連アイテムを変更するために、入力ボックスの「変更」イベントにバインドしています。(これは手動で行うことも、ModelBinder プロジェクトを使用して行うこともできます。どちらの方法でも同じように機能します。)
ユーザーはフォーム入力ボックスの値を変更し、送信ボタンをクリックします。モデルが更新され、ビューとフォームが再レンダリングされます。送信ボタンのクリック イベントが押しつぶされます。
Backbone の events プロパティを使用しています。
events : {
'submit form' : 'save'
},
クリックされた DOM 要素が存在しなくなったため、イベントが無視されていることはわかっています。render() 内に小さな setTimeout を配置して、HTML がスワップ アウトされないようにし、期待どおりに動作するようにすることができますが、これには待機が必要です。
私はこれに苦労する最初の人になることはできません.フォームの「変更」イベントをキャプチャし、モデルを更新し、キークリックまたはキープレス情報を失うことなくビューを再描画する標準的な方法は何ですか?
同様に、複数のフォーム項目がある場合、フォームが再描画されるときに内容を変更した後、ユーザーは項目間でタブを移動できません。
更新 1 ~ 3 日後
まだ良い解決策を見つけようとしています。私が試したこと:
- ビューのコンテンツをページ上の別の領域に移動または複製します。クリック イベントはまだ受信されません。
- 標準のビュー イベント オブジェクトの代わりに $(document).on または $(document).live でクリック イベントを登録する
- フォーム全体 (入力とボタン) が再描画されずにまとまるように、フォームを分離します。親要素 (フォームの値に依存する) を再描画し、既に描画されたフォームを再挿入します。これにより、要素をタブで移動できないという関連する問題が修正されますが、クリック イベントは修正されません。
- Firefox 4 では希望どおりに動作しますが、ie9 や chrome では動作しません。*
更新 2 - サンプルコード付き
コメントの 1 つは、いくつかのコードを要求しました。コードを 1 ページに大幅に簡略化し、以下に含めました。実際のアプリケーションはもっと複雑です。以下のような単純なコードを使用すると、変更時にページの一部を手動で再レンダリングすることができます。実際のアプリケーションでは、dustjs テンプレートを使用しています。フォームを再レンダリングしなくても、フォームを含む要素を再レンダリングすると、送信をクリックする際に問題が発生します。複雑なページやモデル、フォームなど、バックボーン アプリケーションに典型的な「パターン」を期待しています。
ほとんどの「デモ」アプリやバックボーンを使用しているサイトでさえ、実際にはユーザーから多くの入力を収集していないプレゼンテーションに重点を置いたアプリのようです。バックボーンに基づいた優れたデータ収集に焦点を当てたアプリケーション/デモを知っていれば、それは役に立ちます。
コード:
<!doctype html>
<html lang="en">
<head>
<script src="libs/jquery.js"></script>
<script src="libs/underscore.js"></script>
<script src="libs/backbone.js"></script>
</head>
<body>
<div id="container"></div>
<script type="text/template" id="edit_user_template">
<h3>Edit User <%=id%> : <%=name%></h3>
<form>
Name: <input type="text" name="name" value="<%=name%>"><br/>
Email: <input type="text" name="email" value="<%=email%>"><br/>
<input type="submit">
</form>
</script>
<script>
var UserModel = Backbone.Model.extend({});
var model = new UserModel({id: '1', name:'Joe', email:'a@a.com'});
var UserView = Backbone.View.extend({
events : {
'submit form' : 'save',
'change input' : 'inputChange'
},
initialize: function(){
this.model.bind('change', this.render, this);
},
render: function(){
var template = _.template($('#edit_user_template').html(), this.model.toJSON());
this.$el.html(template);
},
inputChange : function(evt){
var target = $(evt.currentTarget);
this.model.set(target.attr('name'), target.val());
},
save : function(event){
console.log('saving');
event.preventDefault();
//this.model.save();
}
});
var view = new UserView({model: model, el: '#container'});
view.render();
</script>
</body>
</html>