2012-03-28 6 views
1

ネストされたテンプレートを使用する必要があるモジュールを達成しようとしています。JavaScript/jQuery/AJAXのネストされたテンプレート

私のUIには、基本的にレベル1、レベル2、レベル3といった3つのレベルがあります。 ページが表示されたら、レベル1のみをレンダリングする必要があります。 レベル1の任意の要素の「展開」ボタンをクリックすると、レベル1の選択された要素より下のレベル2の要素(すべてではない)をレンダリングする必要があります。

ユーザーは、レベル2の要素に対応するレベル3をレンダリングする必要があります。

要約すると、左側のWindowsエクスプローラのナビゲーションバーのようにする必要があります。

+1

チェックアウト私の更新の答え... –

+0

単に素晴らしい.. !!!再度、感謝します.. –

答えて

1

一般に、各レベルに別々のコンポーネントを定義し、各コンポーネントにテンプレートを割り当て、expand()/collapse()メソッドを実装する必要があります。コンポーネントが最初に折りたたまれている場合は、初期化時に子アイテムをレンダリングする必要はありません。子コンポーネントを展開するときにのみレンダリングします(子コンポーネントの適切なテンプレートが使用されます)。

あなたが仕事をしようとしている基本的なコードを提供してください、そう簡単にあなたを助けるでしょう。

テンプレートを使用する単純なレンダリングフローを備えたウィジェットシステムのクイックプロトタイプです。私はあなたのアプリケーションのような何かをしたいと思います。それは最適化されていません、それはあなたのフレームワークがどのように見えるかのアイデアです。

/** 
* Widget constructor 
*/ 
var Widget = function(config) { 
    // apply config 
    $.extend(this, config); 
    // attempt to render 
    this.render(); 
}; 

/** 
* Widget prototype 
*/ 
$.extend(Widget.prototype, { 
    // render target 
    renderTo: null, 
    // template 
    tpl: '<div class="container-panel">' + 
      '<p>${txt}</p>' + 
      '<div class="items-container"></div>' + 
     '</div>', 
    // template data 
    tplData: null, 
    // child items array 
    children: null, 
    // initial collapsed state 
    collapsed: false, 
    // widget's root element 
    el: null, 
    // default render target selector for child items 
    renderTarget: '.items-container', 

    render: function() { 
     var me = this, 
      renderDom 

     // render the widget 
     if(!this.rendered && this.renderTo && this.tpl) { 
      renderDom = $.tmpl(this.tpl, this.tplData); 
      // assume that first element is widget's root element 
      this.el = renderDom[0]; 
      $(this.renderTo).append(renderDom); 

      // clear the reference 
      renderDom = undefined; 

      // THIS IS JUST EXAMPLE CODE! Bind click handler... 
      $(this.el).find('p').first().click(function() { 
       me.collapsed ? me.expand() : me.collapse(); 
      });  

      // find render target for children 
      this.renderTarget = $(this.el).find(this.renderTarget).first(); 

      // render children if not collapsed 
      this.renderChildren(); 

      // set rendered flag 
      this.rendered = true; 
     } 
    }, 

    renderChildren: function() { 
     var children = this.children; 
     if(!this.collapsed && children && children.length) { 
      for(var i = 0, len = children.length; i < len; i++) { 
       // render children inside 
       children[i].renderTo = this.renderTarget; 
       children[i].render(); 
      } 
     } 
    }, 

    /** 
    * Expand template method. Override it. 
    */ 
    expand: function() { 
     this.collapsed = false; 
     this.renderChildren(); 
     this.renderTarget.show(); 
    }, 

    /** 
    * Collapse template method. Override it. 
    */  
    collapse: function() { 
     this.collapsed = true; 
     this.renderTarget.hide(); 
    } 
}); 

ここではテンプレートを事前に定義し、ウィジェットの最初の段落要素内のクリックで発生する拡大/折りたたみロジックをハードコードしました。

// Using our widgets 
var containerPanel = new Widget({ 
    tplData: {txt: 'Hello world!'}, 
    renderTo: $('body'), 
    collapsed: true, 
    children: [ 
     new Widget({ 
      tplData: {txt: '&nbsp;&nbsp;Child 1'}, 
      collapsed: true, 
      children: [ 
       new Widget({ 
        tplData: {txt: '&nbsp;&nbsp;&nbsp;&nbsp;Child 1.1'} 
       }), 
       new Widget({ 
        tplData: {txt: '&nbsp;&nbsp;&nbsp;&nbsp;Child 1.2'} 
       }), 
       new Widget({ 
        tplData: {txt: '&nbsp;&nbsp;&nbsp;&nbsp;Child 1.3'} 
       }) 
      ] 
     }), 
     new Widget({ 
      tplData: {txt: '&nbsp;&nbsp;Child 2'} 
     }) 
    ] 
}); 

あなたはjsFiddleでライブの例を見ることができます::http://jsfiddle.net/dipish/XDmWq/ ちょうど項目をクリックすると、動的に生成されるマークアップを見て

これは、あなたがウィジェットを使用する方法です。

私は、コードは自明だと思いますが、ご質問をお気軽に。コードはjQuery Templates Pluginを使用していますが、便宜上のものです。

ウェブアプリケーションに複雑なコンポーネントがたくさんある場合は、ExtJSDojo Toolkitのような裸のjQueryよりも深刻なものを使用することができます。このようなフレームワークは、通常、便利なクラスシステムと、他の多くのものの上に構築するための基本ウィジェット/コンポーネントロジックを提供します。

幸運を祈る!

+0

私は基本的なコードを開発しています。 はASApを送信します。 :) –

+0

ドミトリーthats正確に私が必要なもの.. PS:毎回子を追加するほとんどのグリッチがありますが、終了時にリストをクリアしませんが、私はそれを処理することができます..ありがとう... !!! :D:D:D –

+0

あなたは大歓迎です! '終了時にリストをクリアする 'とは、パネルが折りたたまれているときに子HTMLを取り除くことです。その場合は、 'this.renderTarget.empty();'を 'collapse()'メソッドに追加してください。しかし親パネルが展開されるたびに子どもを再レンダリングすることによるパフォーマンス上のオーバーヘッドがあるので、それは良い考えではないと私は考えています。 –

1

マークアップがどのように表示されるかは、さらに具体的にする必要があります。しかし、ここにおおまかな例があります:

//run this puppy when we need to append stuff 
var dynamicAppend = function(data, container) 
{ 
    var ul = container.children().slice(1,2); 
    var len = data.length; 
    for(var i = 0; i < len; i++) 
    { 
    var markup = [ 
    "<li class='" + data[i].thing + "'>", 
     "<span class='second_toggle' data-stuff='" + data[i].other_thing + "'></span>", 
     "<ul>", 
     "</ul>", 
    "</li>" 
    ]; 
    ul.append(markup.join()); 
    } 
} 

//do ajax stuff 
var handleAjax = function(data, container) 
{ 
    var json = { unique: data } 
    $.ajax({ 
    url: '', 
    data: json, 
    success: function(data) 
    { 
     if(data.success === 'your_flag' && data.newStuff) 
     { 
     dynamicAppend(data.newStuff, container); 
     } 
    } 
    }); 
} 

//first, you'll click the toggle 
var expand_toggle = $('.toggle'); 
expand_toggle.click(function(e){ 
    var that = $(this); 
    //grab some data that identifies the unique container you want to append to 
    var unique_id = that.data('some_identifier'); 
    var container = that.parents('.parent_container_class:first'); 
    handleAjax(unique_id, container); 
}); 

私は個人的にこれをコンストラクタに入れてOOPスタイルにしますが、そのアイディアを得ることができます。

はここにいくつかのマークアップです:

<div class='parent_container_class'> 
    <span class='toggle' data-some_identifier='special_identifier_here'></span> 
    <ul></ul> 
</div> 
関連する問題