6

連絡先マネージャーの backbone.js にビュー/編集ビューを実装しています。Web は、ContactView および ContactEdit と呼ばれる子ビューを持つ Contact クラスを作成することを提案しました。問題は、これらが DOM で同じ el を占有する必要があるため、親内に子をネストできないことです。これは、外側から見ると、子が非公開であるかのように、親ビューが Contact のみを参照するようにしたいからです。私はこれを試しましたが、初めてrender()で動作します:

initialize: function() {
    this.view[0] = new CL.Views.ContactView({model: this.model, el: this.el});
    this.view[1] = new CL.Views.ContactEdit({model: this.model, el: this.el});
},
render: function() {
    this.view[0].render();
    return this;
}

しかし、その後、ビューを交換することはできません。this.view[0].remove() と考えられるすべてのことを試しましたが、ブラウズビューと編集ビューを同じelを使用して互いに交換することはできません。

これは、1 つのビュー内に 2 つのテンプレートを配置し、それらを交換する方がよいことを意味すると考えていますが、これは既にほとんど機能しています。backbone.js は、DOM の同じレベルのビューの継承をうまく処理できないと思います。

私は backbone.js 拡張機能を避けたいと思っていますが、それらが実装するどんなパターンにも従うつもりです。ビュー/編集はアプリのフォームの一般的なパターンであるため、これを「正しい」方法で実行しようとしています。

PSこの問題を説明する別の方法は、ビューを囲む親ビューがない場合、ビューを非表示にしてbackbone.jsの別のビューに置き換える方法です。

ご協力いただきありがとうございます。

4

3 に答える 3

1

のビューが必要なのか、単一の を処理するビューが必要なCollectionのかよくわかりません。ModelsModel

単体モデルのビューであれば、

そうすれば、1 つのビューに固執することができます。編集機能を有効または無効にするアクションをリッスンするイベントをいくつか用意するだけです。(dom 要素に contenteditable="true" を設定することでもこれを行うことができます)

backbone.marionetteや chaplinjsなどのツールを使用することを強くお勧めします。彼らはあなたの時間を大幅に節約します。

以下は Backbone.Marionette の例です。

例のテンプレート

<script type="text/template" id="contact-view-template">
  <span data-bind="firstName"></span>
  <span data-bind="lastName"></span>
  <span data-bind="email"></span>
  <a href="#" data-action="edit">
  <a href="#" data-action="save" style="display:none">
</script>

ビューコード:

ContactView = Marionette.ItemView.extend({
  template:"#contact-view-template",
  events:{
    "click [data-action=edit]":"edit",
    "click [data-action=save]":"save"
  },
  edit:function(){
    this.$("[data-action=edit]").hide();
    this.$("[data-action=save]").show();
    this.$("[data-bind]").attr("contenteditable",true);
  },
  save:function(){
    var value = {};
    _.each(this.$("[data-bind]",function(el){
      value[el.dataset['bind']]= $(el).val() || $(el).text();
    }));
    this.model.set(value);
    // add your validation here
    this.model.save();
  }
});

複数の編集ビューが必要な場合は、次のようにします。

ContactListEditView = Marionette.CompositeView.extend({
  itemView:ContactView.extend({
    tagName:"li"
  }),
  itemViewContainer:"ul",
  template:_.template("<h1>ContactList</h1><p>feel free to edit</p><ul></ul>")
});

1 つの編集ビューと複数の編集不可ビューが必要な場合

(重大なエラーが発生していないことを願っています):

ContactEditView = Marionette.ItemView.extend({
  template:"#contact-edit-view", // your template & bindings
  events:{
    "click [data-action=save]":"save"
  },
  save:function(){
    var value = {};
    _.each(this.$("[data-bind]",function(el){
      value[el.dataset['bind']]= $(el).val() || $(el).text();
    }));
    this.model.set(value);
    this.model.save();
  }
});


ContactListView = Marionette.CompositeView.extend({
  itemView:Marionette.ItemView.extend({
    template:"#contact-view-template",
    events:{
      "click [data-action=edit]":"edit"
    },
    edit:function(){
      this.trigger("edit",this);
    }
  }),
  regions:{
    "edit":"[data-region=edit]"
  },
  initialize:function(){
    this.on("itemview:edit",function(view){
      this.edit.show(new ContactEditView({model:view.model}));
    }.bind(this));
  }
});
于 2013-01-26T00:20:34.627 に答える
0

親ビューが子ビューと同じ要素を共有しているという事実から問題が発生すると思います。ContactViewまたはビューをレンダリングするContactEditと、DOM 要素が置き換えられます。またremove、子ビューをレンダリングすると、同じ要素であるため、(定義により) 親ビュー要素も削除されます。

代わりに、子ビューがコンテナ要素にレンダリングされるように、親ビューを構成する必要があります。何かのようなもの

<!-- .contact-container is the parent view el -->
<section class="contact-container">

</section>

次に、子ビューをコンテナーにレンダリングします。

initialize: function() {
  //don't give the views an element, let them render into the detached
  //element generated by Backbone
  this.view[0] = new CL.Views.ContactView({model: this.model});
  this.view[1] = new CL.Views.ContactEdit({model: this.model});
  this.currentViewIndex = 0;
},
render: function() {
  //replace the contents with the new view
  this.view[this.currentViewIndex].render();
  this.$el.html(this.view.el);

  return this;
},

swap: function() {
  var i = this.currentViewIndex;
  this.view[i].remove();
  //toggle current view between 0 and 1
  this.currentViewIndex = i === 0 ? 1: 0;
  this.render();
}

それからあなたは得る

<!-- .contact-container is the parent view el -->
<section class="contact-container">
  <div><!-- your child element --></div>
</section>
于 2013-01-25T10:22:31.340 に答える
0

私があなたの質問を正しく理解していればView、同じ .xml で自由に操作できるように、ベースから継承するビューが必要ですModel

/** Declare base View with specific Model. */
var baseView = Backbone.View.extend({
    model: someModel
});

var contactView = baseView.extend({
   initialize: function() {
        /** Do work specific to contact view. */
   }
});

var editContactView = baseView.extend({
   initialize: function() {
       /** Do work specific to contact edit. */
   }
});

var mainView = Backbone.View.extend({
   initialize: function() {
       /** Initialize two contact views */
       new contactView({ });
       new editContactView({ });
   }
});
于 2013-01-25T23:23:39.160 に答える