20

Backbone と Marionette を使用して、ページのメイン コンテンツ div に入る新しいレイアウトを作成しました。レイアウトは次のようになります。

<div id='dash-sidebar'>
    <div id='dash-profile'></div>
    <div id='dash-nav'></div> 
</div>
<div id='dash-content'></div>

問題は、レイアウトをレンダリングすると、バックボーンが自動的に div にラップしてから、次のようにメイン コンテンツ div に配置することです。

<div id='main-content'>    
  <div>
    <div id='dash-sidebar'>
      <div id='dash-profile'></div>
       <div id='dash-nav'></div> 
    </div>
    <div id='dash-content'></div>
  </div>
</div>

tagName で要素を変更できることはわかっていますが、テンプレートを完全にラップせずに、ページのメイン コンテンツ div に直接挿入することはできますか?

4

4 に答える 4

13

各バックボーン ビューは、1 つの要素で表す必要があります。最初の HTML ブロックには 2 つの要素があるため、最初に外側の div でラップしないとビューで表すことができません。

レイアウトをリファクタリングして、main-content領域も含めることができますか? 次に、レイアウトelは外側の div 全体に対応します。

別の試みとして、Backbone.View のsetElement()メソッドを使用して外側の div の作成をオーバーライドし、View の要素に必要な HTML を手動で挿入します。何かのようなもの:

onRender: function() {
    this.setElement( /* the HTML you want for your layout */ );
}

ただし、1 つではなく 2 つの親要素を持つ HTML を渡した場合、これがどのように機能するかはわかりません。

于 2012-07-06T16:52:36.470 に答える
10

EDIT3:警告!この回答は古くなっている可能性があります。この回答が機能しなくなり、調査する時間がなかったというコメントを受け取りました (私は個人的にこの方法を使用していません)。

私は Twitter/Bootstrap を UI ライブラリとして使用するのが好きで、デフォルトのタグ ラッピングが原因でテーブルのスタイリングに問題がありました (具体的には<div>、私<tbody>と私<tr>の の間)。

掘り下げた後、マリオネットのドキュメントで がをどのように取り付けるRegionかについて見つけました。バックボーンは、さまざまな属性から を構築し、構築された要素を最新の状態に保ち、いつでもレンダリングできるようにします。だから私は、もし親なら、なぜHTMLコンテンツを使わないのですか? マリオネットは、カスタムを作成する方法も提供しますViewelelViewview.elRegion

Regionオーバーライドされたopen関数を使用してカスタムを作成することで、すべてを実行することができました。そうすれば、タグでラップする領域とラップしない領域を指定できます。次のサンプル スニペットでは、カスタムの非ラッピングRegion( NowrapRegion) を作成し、それを my Layout( MyLayout)で使用し<tbody>ます (実際のプログラムで渡したビューは<tr>s を作成します)。

var NowrapRegion = Marionette.Region.extend({
  open: function(view){
    this.$el.html(view.$el.html());
  }
});

var MyLayout = Marionette.Layout.extend({
  template: templates.mylayout,
  regions: {
    foo: '#foo',
    columns: '#columns', //thead
    rows: { selector: '#rows', regionType: NowrapRegion } //tbody
  }
});

ブーム!必要なときはラッピングし、不要なときはラッピングしません。

編集:これは、レベルeventsで適用される影響を与えるようです。*Viewまだ調べていませんが、トリガーされていないようです。

これが「正しい」方法であるかどうかはわかりません。@derick-bailey がこれを見たら、どんなフィードバックでも歓迎します。

EDIT2: @chris-neale は次のことを提案しました。これはまだ確認していませんが、健全なようです。ありがとう!

ビューで html をコピーするのではなく、子ノードでディープ クローンを使用すると、イベントとデータが維持されます。

var NowrapRegion = Marionette.Region.extend({
  open: function(view){
    view.$el.children().clone(true).appendTo(this.$el);
  }
});
于 2013-02-26T00:44:38.887 に答える
6

更新: Marionette.Layout はバックボーン ビューの拡張であるため、これは通常の動作です。バックボーンのドキュメントを参照してください。

「el」プロパティは、ブラウザで作成された DOM オブジェクトを参照します。すべての Backbone.js ビューには「el」プロパティがあり、定義されていない場合、Backbone.js は独自の空の div 要素を構築します。

したがって、私の以前の回答はあなたの問題とは何の関係もありませんでした。申し訳ありません。

アップデート:

この件に関して Backbone gitHub でissue 546が見つかりました(wontfix としてクローズされました)。

バックボーン ビューを使用する利点の大部分は、テンプレートがレンダリングされているかどうかに関係なく (多くのビューには複数のテンプレートがあります)、ビューがDOM かどうか。

これにより、ビューを作成してDOMに追加し、後でレンダリングして、すべてのイベントが正しくバインドされていることを確認できます(view.elから委任されているため)。

上記の特性を維持しながらビューが「完全な」テンプレートを持つことを可能にする優れた戦略を思いつくことができれば...それについて話しましょう-しかし、ルート要素のコンテンツをレンダリングすることなく存在できるようにする必要がありますテンプレート (後で到着する可能性のあるデータに依存する場合があります)、およびビューが複数のテンプレートを簡単に持つことができるようにする必要があります。

于 2012-06-25T22:49:29.083 に答える
1

私はほとんど同じことを達成したいと思っていました。テンプレートにすべての HTML マークアップを入れて、後は Backbone に任せたいです。そこで、余分な「div」を削除する次のスニペットを書きました。

まず、tagName を 'detect' に設定し、最初のレンダリング後に、ビュー内の最初の要素の tagName を検出します。明らかに、これはテンプレートに独自のラッパーを提供する場合にのみ機能します。

// Single table row inside tbody
tableRowView = Backbone.Marionette.ItemView.extend({
  tagName: 'detect',
  template: function(data) {
    return Handlebars.templates['tablerow/single'](data);
  },
  onRender: function() {
    if (this.tagName == 'detect')
      this.tagName = this.$el.children().first().prop('tagName').toLowerCase();
    this.setElement( this.$el.children( this.tagName ) );
    var $parent = this.$el.parent( this.tagName );
    if ($parent.length) {
      this.$el.detach();
      this.$el.insertAfter($parent);
      $parent.remove();
    }
  },
  modelEvents: {
    "change": "render"
  }
});

テンプレート:

<tr>
  <td>{{artist}}</td>
  <td>{{title}}</td>
  <td>{{length}}</td>
</tr>

しかし、私はそれを少しいじっただけです - このアプローチが引き起こす可能性のある問題 (パフォーマンス、メモリ、ゾンビなど) を誰かが見つけたら、私はそれらについて学ぶことに非常にオープンです.

ところで、これはおそらくプラグインに簡単にパッケージ化できます。

于 2013-03-15T18:07:57.657 に答える