سؤال

Trying to convert very complex jQuery template code to jsRender. I have this each loop in the old code:

<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>

I have edited it to look like this:

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

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

But it does not work. If I change it to be:

<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>

It draws the images to display but the function does not run on the image array. But if I leave the Images array without being wrapped in a function and move the for loop to inside the template it breaks.

How would I convert this scenario?

هل كانت مفيدة؟

المحلول

An important difference between JsRender and jQuery Templates is that JsRender does not let you access global functions or variables directly within template markup.

This is a design choice, related to security concerns, and separation of concerns. But unlike "logicless" template languages, such as Mustache, JsRender provides very powerful and flexible support for logic within the template - while still preventing random mixing of code and markup.

One way to include logic is to encapsulate it outside the template in helper functions, but in that case you need to register the helper function, either globally, or for the specific template, or else pass it in on an options object with the render call.

See www.jsviews.com/#helpers and www.jsviews.com/#samples/jsr/helpers for documentation. (There are many other samples also on the www.jsviews.com site showing use of helper functions)

So in your case you can do

function filterOutMainImages(images) { ... }

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

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

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

Or

function filterOutMainImages(images) { ... }

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

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

Assuming your filterOutMainImages() function returns a filtered array, and with your helper registered or passed in as above, then the following templates should work:

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

<script id = "largeTemplate" type="text/x-jsrender">
    {{for ~filterImages(Images) tmpl="#imagesTemplate"/}}
</script>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top