2012-03-28 73 views
1

我想完成一個模塊,我需要使用嵌套模板,我卡在如何可以做到這一點。在JavaScript/jQuery/AJAX嵌套模板

基本上在我的用戶界面中有3個級別,例如說1級,2級,3級。 所以當頁面顯示時,我只需要渲染級別1。 但是當用戶點擊level1的任何元素的「展開」按鈕時,我需要呈現級別1的選定元素下的級別2(不是全部)的相應元素。

現在,當用戶點擊「展開」級別2的元素,相應的級別3應呈現..

總結它應該就像Windows資源管理器的左側導航欄。

+1

看看我的更新答案... – 2012-03-28 11:49:43

+0

根本真棒.. !!!再次感謝.. – 2012-03-28 13:04:29

回答

1

通常,您應該爲每個級別定義單獨的組件,爲每個組件分配模板並實施類似expand()/collapse()方法。如果一個組件最初被摺疊(你的情況),那麼它不應該在初始化時渲染子項目,它只會在展開它們時纔會渲染它們(將使用適當的子組件模板)。

請提供您正在努力工作的基本代碼,以這種方式幫助您會更容易。

這是一個使用模板的簡單渲染流程的Widget系統的快速原型。我想你在你的應用程序中需要類似的東西。它沒有被優化,它只是你的框架看起來的一個想法。

/** 
* 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(); 
    } 
}); 

在這裏,我預先定義的模板和硬編碼上點擊widget的第一款元素內發生的展開/摺疊邏輯。

這是你將如何使用的部件:

// 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,但這只是爲了方便。

如果您的網絡應用程序中有許多複雜的組件,您可能想要使用比裸露jQuery更嚴重的內容,例如ExtJSDojo Toolkit。除了很多其他的東西外,這樣的框架通常爲您提供了一個方便的類系統和基礎構件/組件邏輯。

祝你好運!

+0

嘿德米特里感謝我正在開發基本代碼的迴應。 將發佈ASAp。 :) – 2012-03-28 08:23:21

+0

德米特里多數民衆贊成正是我需要.. 聚苯乙烯:有一點小故障,它每次增加孩子,但沒有清除出口清單,但我可以處理,我想..謝謝...! :D:D:D – 2012-03-28 13:02:26

+0

不客氣!通過'清除退出列表'你的意思是當你的面板崩潰時刪除子html?如果是這樣,將'this.renderTarget.empty();'添加到'collapse()'方法。但我不認爲這是一個好主意,因爲每當父面板展開時,重新渲染子項會導致性能開銷。 – 2012-03-28 13:20:18

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>