2012-12-30 20 views
6

Böyle bir veri yapısına sahip varsayarsak:Özyineleme doT.js ile

{ list: [ { 
     name: "1", 
     children: [{ 
       name: "1.1", 
       children: [] 
      }, 
      { 
       name: "1.2", 
       children: [{ 
        name: "1.2.1", 
        children: [] 
        } 
       ] 
      } 
     ] 
     }, 
     { 
     name: "2", 
     children: [{ 
       name: "2.1", 
       children: [{ 
        name: "2.1.1", 
        children: [] 
        },   
        { 
        name: "2.1.2", 
        children: [] 
        },    
        { 
        name: "2.1.3", 
        children: [] 
        } 
       ] 
      }, 
      { 
       name: "2.2", 
       children: [] 
      }, 
      { 
       name: "2.3", 
       children: [] 
      } 
     ] 
     }, 
     { 
     name: "3", 
     children: [{ 
       name: "3.1", 
       children: [] 
      } 
     ] 
     } 
    ] 
} 

ben yinelemeli nesne geçmesi ve iç içe listeleri inşa edecek doT.js içeren bir şablon oluşturma hakkında nasıl gitmek? Bir özyinelemeli fonksiyonu ile JS doğrudan html dize Bina

yalındır yeterlidir:

var html = ""; 
function buildList(a){ 

    if (a.length == 0){return}; 

    html += "<ul>"; 
    for (var i = 0; i < a.length; i++) 
    { 
     html += "<li>" + a[i].name; 
     buildList(a[i].children); 
     html += "</li>"; 
    } 
    html += "</ul>";    
} 
buildList(data.list); 

$("#out").html(html); 


Ama doT.js ile (http://jsfiddle.net/fergal_doyle/WN8hZ/5/)

bu ben ne var ve bundan sonra stumped ! ( http://jsfiddle.net/fergal_doyle/BTZpu/4/)

DÜZENLEME: partials kullanarak bunu başarmak için çalışıyordu

{{ function buildList(a) { }} 

    {{?a.length}} 
    <ul> 
     {{~a :v}} 
     <li> 
      {{=v.name}} 
      {{ buildList(v.children); }} 
     </li> 
     {{~}} 
    </ul> 
    {{?}} 

{{ } }} 

{{ buildList(it.list); }} 

Ben değerlendirmede (http://jsfiddle.net/fergal_doyle/he8AN/) ile bazı JS karıştırarak yapabilirsiniz. Bir ul snippet'i tanımlamak, o snippet'in kendisini bir dizide param olarak geçirmesini gerektiriyor, ancak "çok fazla özyineleme" hatası alıyorum. Aşağıda çalışmak için herhangi bir yolu varsa, bence yukarıda bence çok daha temiz. (http://jsfiddle.net/fergal_doyle/qazGe/4/)

{{##def.ul:a: 
    <ul> 
    {{~a :value}} 
     <li>{{=value.name}}{{#def.ul:value.children}}</li> 
    {{~}} 
    </ul> 
#}} 

{{#def.ul:it.list}} 

cevap

3

Sorun derleme süredir. doT.js kısmi olarak yineleme işlemiyor gibi görünmüyor. Siz yineleme kodu {{#def.ul:value.children}} doT.js kütüphanesini, işlevinizin içeriği ile sınırsız şekilde çözer/değiştirir. Bunun üstesinden gelmenin bir yolu, kısmi parçanızdaki kısmi kısma bakmak için arguments.callee'u kullanmaktır.

function resolveDefs(c, block, def) { 
    return ((typeof block === 'string') ? block : block.toString()) 
    .replace(c.define || skip, function(m, code, assign, value) { 
     if (code.indexOf('def.') === 0) { 
      code = code.substring(4); 
     } 
     if (!(code in def)) { 

      // HANDLE RECURSION START 
      value = value.replace(c.use || skip, function(m, recursiveCode) { 
       if (c.useParams) return recursiveCode.replace(c.useParams, function(m, s, d, param) { 
        if(d == code) { 
         var ret = s + "{{=arguments.callee("; 
         if(param) 
          ret += param; 
         return ret + ")}}"; 
        } 
       }); 

      }) 
      // HANDLE RECURSION END 

      if (assign === ':') { 
... 
: İşte (denenmemiş) Aşağıdaki şekilde kendi kütüphanesinde aynı fikri uygulayabilir kütüphanenin sizin FIDDLE

{{##def.ul:a: 
    <ul> 
    {{~a :value}} 
    <li>{{=value.name}}{{=arguments.callee(value.children)}}</li> 
    {{~}} 
    </ul> 
#}} 

{{#def.ul:it}} 

yazar (lar) ın bir çatal bu