【问题标题】:Trying to run a function on an array in a, for loop, using jsrender尝试使用jsrender在for循环中的数组上运行函数
【发布时间】:2013-10-29 18:34:19
【问题描述】:

试图将非常复杂的 jQuery 模板代码转换为 jsRender。我在旧代码中有每个循环:

<script id = "imagesTemplate" type="text/x-jquery-tmpl">
    {{each(i,imgUrl) twoAcross_filterOutMainImages(OfferGroup.Images)}}
        <img src="{{= imgUrl}}" />
    {{/each}}
</script>

<script id = "largeTemplate" type="text/x-jquery-tmpl">
    {{tmpl "#imagesTemplate"}}
</script>

<div id="LARGE"  class="mainContent"></div>
<script>
     currentOffer = offerGroups[0].Groups[0];
     $( "#LARGE" ).html( $( "#largeTemplate" ).render( currentOffer ) ); 
</script>

我已将其编辑为如下所示:

{{for ~filterOutMainImages(Images) tmpl="#imagesTemplate"/}}

<div id="LARGE"  class="mainContent"></div>
<script>
     currentOffer = offerGroups[0].Groups[0];
     $( "#LARGE" ).html( $( "#largeTemplate" ).render( currentOffer ) ); 
</script>

但它不起作用。如果我将其更改为:

<script id = "imagesTemplate" type="text/x-jquery-tmpl">    
        <img src="{{= imgUrl}}" />
</script>

<script id = "largeTemplate" type="text/x-jquery-tmpl">
    {{for Images tmpl="#imagesTemplate"/}}
</script>

<div id="LARGE"  class="mainContent"></div>
<script>
     currentOffer = offerGroups[0].Groups[0];
      $( "#LARGE" ).html( $( "#largeTemplate" ).render( currentOffer ) ); 
</script>

它绘制要显示的图像,但该函数不在图像数组上运行。但是,如果我离开 Images 数组而不被包裹在一个函数中,并将 for 循环移动到模板内部,它就会中断。

我将如何转换这种情况?

【问题讨论】:

  • 你如何声明你的辅助函数:filterOutMainImages?是的,展示一个小提琴会很好......应该是{{:imgUrl}}。上面的第二个版本缺少模板周围的
  • 我在使用小提琴界面进行设置时遇到了问题,所以我在这里发布了一个测试页面:mcgrathdesigns.com/test

标签: javascript templates jquery-templates jsrender


【解决方案1】:

JsRender 和 jQuery 模板之间的一个重要区别是 JsRender 不允许您直接在模板标记中访问全局函数或变量。

这是一种设计选择,与安全问题和关注点分离有关。但与 Mustache 等“无逻辑”模板语言不同,JsRender 为模板内的逻辑提供了非常强大和灵活的支持——同时仍然防止代码和标记的随机混合。

包含逻辑的一种方法是将其封装在模板之外的辅助函数中,但在这种情况下,您需要注册辅助函数,无论是全局还是特定模板,或者通过渲染调用将其传递给选项对象。

有关文档,请参阅 www.jsviews.com/#helperswww.jsviews.com/#samples/jsr/helpers。 (www.jsviews.com 网站上还有许多其他示例显示了辅助函数的使用)

所以你可以这样做

function filterOutMainImages(images) { ... }

// Register helper
$.views.helpers({
    filterImages: filterOutMainImages 
});    

var html = $("#largeTemplate").render(currentOffer);

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

或者

function filterOutMainImages(images) { ... }

var html = $("#largeTemplate").render(
    currentOffer,
    {filterImages: filterOutMainImages} // Pass in helper
);

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

假设您的 filterOutMainImages() 函数返回一个过滤后的数组,并且您的助手如上注册或传入,那么以下模板应该可以工作:

<script id = "imagesTemplate" type="text/x-jsrender">    
    <img src="{{>imgUrl}}" />
</script>

<script id = "largeTemplate" type="text/x-jsrender">
    {{for ~filterImages(Images) tmpl="#imagesTemplate"/}}
</script>

【讨论】:

  • 鲍里斯非常感谢!!
  • 实际上 Boris 如果您查看我的测试页面,它似乎仍然无法正常工作。 mcgrathdesigns.com/test 是我写数组的方式吗?它实际上看起来可能是我试图调用循环中每个项目的方式。似乎没有“将每个处理为...”我在#LARGE div 的顶部写了一条注释行,显示数组正在进入 for 循环。
  • 得到它只是使用 #view.data 就好像它是数组 [i] 在 for 循环中或 each 在每个循环中。所以在你上面的例子中 {{>imgUrl}} 应该是 {{:#view.data}}
  • 如果你的函数返回一个字符串数组,它会是 {{:#data}} - 它是 {{:#view.data}} 的简写。或者您可以使用 {{>#data}}、{{attr:#data} 或 {{url:#data}} 进行编码 - 请参阅 jsviews.com/#converters()。考虑到你以前的版本,我假设你返回了一个具有 imgUrl 属性的对象数组。
  • 哇,你的图书馆真棒!很高兴有这些选择,干得好。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 2023-03-14
  • 2020-09-13
  • 1970-01-01
  • 2011-01-31
  • 1970-01-01
相关资源
最近更新 更多