0

我想从ajax调用(它提供了我需要的JSON)触发的函数中使用underscore.js呈现模板成功。Underscore.js - 模板不能在第一时间编译

我遇到了一些奇怪的现象:

  • 当AJAX调用成功,第一次,我得到这个错误:

Uncaught ReferenceError: response is not defined

  • 当它成功了第二次,没有刷新页面,一切都按预期进行。

我的JSON具有这样的结构:

{ 
    data: [ 
     item1: {count: "1", url: "http://example1.com", id:"arstd", formatted:"1"}, 
     item2: {count: "53", url: "http://example2.net", id:"hneio", formatted:"0"}, 
     ... 
    ] 
} 

我underscore.js模板:

<script type="text/template" id="count_template"> 
    <% _.each (response.data, function (item) { %> 
    <a href="<%- item.url %>"> 
     <li> 
      <p id="<%- item.id %>" class="name"> 
       <%- item.formatted %> 
      </p> 
      <p id="<%- item.id %>_count" class="count"> 
       <%- item.count %> 
      </p> 
     </li> 
    </a> 
    <% }); %> 
</script> 

我的AJAX回调函数:

var on_result_count_fetched = (function() { 
    var totals = $(".regions .count"); 
    var ajax_loader = $("#ajax_loader"); 
    var c_tl = $('#count_template'); 
    var count_div = $('#res_count'); 
    //getting the template for the count response 
    if (c_tl) { 
     var c_template = _.template(c_tl.html()); 
    } 
    _.templateSettings.variable = "response"; 
    //real callback 
    return function (response) { 
     if (response.redirect) { 
      window.location.replace(data.redirect); 
     } else { 
      //hide loading animation 
      ajax_loader.hide(); 
      if (!response && _.isEmpty(response)) { 
       var tmp = $("<button>In case of fail: do this other action!</button>") 
       tmp.click (function() { 
        fetch_results ("searx"); 
       }); 
      } else { 
       console.log(response); 
       var tmp = c_template(response); 
      } 
      count_div.empty(); 
      count_div.append(tmp); 
     } 
    } 
}()); 

回答

0

当你说_.template(some_string),下划线将使用的值解析some_string并将其转换为JavaScript函数。一旦_.template已向您返回已编译的模板函数,_.templateSettings的内容就不再重要。

你做这样的事情:

var t = _.template(some_string); 
_.templateSettings.variable = "response"; 

所以你_.templateSettings.variable分配来得太晚而影响您的_.template电话。您需要调用_.template所以在此之前调整_.templateSettings

if (c_tl) { 
    var c_template = _.template(c_tl.html()); 
} 
_.templateSettings.variable = "response"; 

应该更像:

if (c_tl) { 
    _.templateSettings.variable = "response"; 
    var c_template = _.template(c_tl.html()); 
} 

或者你可以完全跳过_.templateSettings说:

var tmp = c_template({ response: response }); 

致电时模板功能。如果您的其他模板不希望使用response来访问其数据,则可能会产生副作用_.templateSettings。完全在一个地方全局配置_.templateSettings,或者完全保留一个地方往往效果更好。