2012-12-15 140 views
3

我想將微模板合併到我正在構建的插件中。我已經掌握了所有的優點,但是當涉及到數據中的嵌套數組時,我遇到了問題。非常感謝您的幫助。這裏是剝離代碼:嵌套數組微模板

var locations = [{ 
      "name": "Disneyland California", 
      "address": "1313 North Harbor Boulevard" 
     }, 
     { 
      "name": "Walt Disney World Resort", 
      "address": "1503 Live Oak Ln" 
     }], 

     tmplData = [{ 
        location: locations[0], 
        foo: "bar" 
       }], 

     template = "Shipping From:<br><b>{{location.name}}, {{foo}}", 
     attachTemplateToData; 

     attachTemplateToData = function(template, data) { 
      var i = 0, 
       len = data.length, 
       fragment = ''; 
      function replace(obj) { 
       var t, key, reg; 
       for (key in obj) { 
        reg = new RegExp('{{' + key + '}}', 'ig'); 
        t = (t || template).replace(reg, obj[key]); 
       }  
       return t; 
      } 
      for (; i < data.length; i++) { 
       fragment += replace(data[i]); 
      } 
      console.log(fragment); 
     }; 
     attachTemplateToData(template, tmplData); 

日誌:

bar,{{location.name}} 

正如你可以在執行console.log看到「富」出來就好了,但我還需要得到「位置。名稱「(」迪士尼樂園加州「)進行渲染。我知道它將是一個嵌套循環,但我不能爲我的生活弄清楚語法。順便說一句,模板解決方案來自這裏:http://net.tutsplus.com/tutorials/javascript-ajax/create-a-makeshift-javascript-templating-solution/ 謝謝!

編輯::: 我期待使位置對象的任何屬性都可以放入模板。例如,如果用戶決定要將locations.city或locations.foo添加到數組中,那麼在模板中,他們只需要{{location.city}}或{{location.foo}}。 我已經能夠通過使用jQuery的tmpl插件來實現這一點,但我並不需要提供所有的東西。我希望像我一樣擁有一個非常完美的版本,只處理上述情況。這是我做過什麼用TMPL插件(工作):

tmplData = [{ 
        locations: settings.locations[i] 
       }]; 

      var tmplMarkup = "Shipping From:<br><b>${locations.name}, ${locations.city}, ${locations.state}</b>"; 
      $.template("deTemplate", tmplMarkup); 
      $.tmpl("deTemplate", tmplData).appendTo("#deResults"); 

回答

0

感謝您的輸入vittore,我終於想通了代碼。這裏是多餘的if語句和正則表達式,我需要有,也是我發現我所需要的.hasOwnProperty功能有太多:

for(subKey in obj[key]){ 
         if (obj[key].hasOwnProperty(subKey)) { 
          reg = new RegExp('{{'+key+'.'+subKey+'}}'); 
          t = (t || template).replace(reg, obj[key][subKey]); 
         } 
        } 

下面是完整的代碼:

var locations = [{ 
     "name": "Disneyland California", 
     "address": "1313 North Harbor Boulevard" 
    }, 
    { 
     "name": "Walt Disney World Resort", 
     "address": "1503 Live Oak Ln" 
    }], 

    tmplData = [{ 
       location: locations[1], 
       foo: "bar" 
      }], 

    template = "Shipping From:<br><b>{{location.address}}, {{foo}}", 
    attachTemplateToData; 

    attachTemplateToData = function(template, data) { 
     var i = 0, 
      j = 0, 
      len = data.length, 
      fragment = ''; 
     function replace(obj) { 
      var t, key, subKey, subSubKey, reg; 
      for (key in obj) { 
       if (obj.hasOwnProperty(key)) { 
        reg = new RegExp('{{' + key + '}}', 'ig'); 
        t = (t || template).replace(reg, obj[key]); 
        for(subKey in obj[key]){ 
         if (obj[key].hasOwnProperty(subKey)) { 
          reg = new RegExp('{{' + key + '.' + subKey + '}}','ig'); 
          t = (t || template).replace(reg, obj[key][subKey]); 
         } 
        } 
       } 
      }  
      return t; 
     } 
     for (; i < data.length; i++) { 
      fragment += replace(data[i]); 
     } 
     console.log(fragment); 
    }; 
    attachTemplateToData(template, tmplData); 
1

,而不是這樣的:

var locations = [{ 
     "name": "Disneyland California", 
     "address": "1313 North Harbor Boulevard" 
    }, 
    { 
     "name": "Walt Disney World Resort", 
     "address": "1503 Live Oak Ln" 
    }], 

    tmplData = [{ 
       location: locations[0], 
       foo: "bar" 
      }], 

    template = "Shipping From:<br><b>{{location.name}}, {{foo}}", 
    attachTemplateToData; 

試試這個:

var locations = [{ 
     name: "Disneyland California", 
     address: "1313 North Harbor Boulevard" 
    }, 
    { 
     name: "Walt Disney World Resort", 
     address: "1503 Live Oak Ln" 
    }], 

    tmplData = [{ 
       location: locations[0].name, 
       foo: "bar" 
      }], 

    template = "Shipping From:<br><b>{{location}}, {{foo}}", 
    attachTemplateToData; 

真的它僅僅是.NAME需求約4線! :)

+0

你失去了這種模式背後的想法,因爲你將需要硬編碼每個嵌套的屬性。 – vittore

+0

你是對的。重讀這個問題和原始示例後,答案就簡單多了。我相應地調整了我的答案。 – Tims

+0

謝謝蒂姆斯,我已經想到我可以做到這一點,我想我沒有在問題中指定我真的希望'用戶'能夠不僅向位置對象添加自定義屬性,而且還能夠用模板函數調用它們。例如,可以說有人想爲這兩個地點添加一個「城市」。我希望他們在模板中指定{{locations.city}},並且如果我不知道他們添加了什麼屬性,它就會起作用。即:{{locations.foo}} 我將相應地編輯我的問題。 –

1

你需要的是改變模板識別不僅{{prop}}在匹配代碼相符,但也{{prop.something}}

你可以做到這一點添加另一個if語句新的正則表達式。

+0

這正是我正在尋找的,除非我真的不知道如何去做這件事。如果你有一個例子,我會更感激。我將從你的解釋中繼續研究它。謝謝! –

+0

我會把一些代碼放在一起,是的 – vittore