把手:由于没有空白而导致的词汇错误

时间:2018-02-28 09:37:17

标签: javascript handlebars.js

在尝试在Handlebars中编译模板时,我发现了一个奇怪的错误。

我只是在模板HTML中使用ajax,然后修剪结果以确保没有空格,但这不应该导致问题。

这是我在slider.hbs中的模板:

<div class="review-cards__title">
    <img src="/img-src/themev2/theme/{{toLowerCase website.source }}-logo.png" alt="">
</div>
<div class="slick-slider">
    {{#each reviews }}
        <div class="review-card">
            <div class="review-card__name">{{ name }}</div>
            <div class="review-card__quote">
                {{ quote }}
            </div>
            <div class="review-card__stars">
                {{#rating-star rating }}
                    <i class="fa fa-star" aria-hidden="true"></i>
                {{/rating-star}}
                {{#rating-empty rating 5 }}
                    <i class="fa fa-star-o" aria-hidden="true"></i>
                {{/rating-empty}}
            </div>
        </div>
    {{/each}}
</div>
<div class="stats">
    {{#ifEquals website.source "JudgeService" }}
        {{#if judgeservice.dealer_id }}
            {{#if judgeservice.dealer_name }}
                <div id="js-widget-button">
                    <a href="https://www.judgeservice.com/en-gb/car-dealership/name/{{nospace judgeservice.dealer_name }}/" target="_blank" title="{{ judgeservice.dealer_name }} - reviewed on JudgeService.com">
                        {{ judgeservice.dealer_name }} - reviewed on JudgeService.com
                    </a>
                </div>
            {{/if}}
        {{/if}}
    {{/ifEquals}}
    <p>Provided By {{ website.source }}</p>
</div>

然后我请求数据并将其发送到另一个方法:

 self.xhttp.onreadystatechange = function() {

            if (this.readyState === 4 && this.status === 200) {
                self.outputData.call(self, self.xhttp.responseText);
            }

然后我当然尝试编译HTML:

outputData(templateHTML) {
        const self = this;

        templateHTML = templateHTML.trim();
        console.log(templateHTML);

        let templateScript = Handlebars.compile(templateHTML);
        let html = templateScript(self.context);

这是我得到的错误,我真的不明白我在这里做错了什么! enter image description here

修改

在运行aJax调用以获取模板之前,我分配了帮助程序。

下面是我的整个aJax调用,如果使用themev2文件夹而不是self.context["website"]["code"]文件夹中的全局模板(它们是相同的),整个脚本都可以正常工作。

getTemplate() {

        const self = this;

        self.xhttp.onreadystatechange = function() {

            // Dealer has template
            if (this.readyState === 4 && this.status === 200) {
                self.outputData.call(self, self.xhttp.responseText);
            }

            // Check for global template
            if (this.readyState === 4 && this.status === 404) {

                self.xhttp.onreadystatechange = function() {
                    if (this.readyState === 4 && this.status === 200) {
                        self.outputData.call(self, self.xhttp.responseText);
                        return;
                    } else if (this.readyState === 4 && this.status === 404) {
                        self.outputData.call(self, null);
                    }
                };
                self.xhttp.open("GET", "/templates/themev2/reviews/panel/" + self.template + ".hbs", true);
                self.xhttp.send();

            }
        };

        self.xhttp.open("GET", "/templates/" + self.context["website"]["code"] + "/reviews/panel/" + self.template + ".hbs", true);
        self.xhttp.send();
    }

1 个答案:

答案 0 :(得分:0)

以下是一个使用与您相同的模板代码的代码段,它按预期编译。我认为您忘记声明自定义助手:toLowerCase,ifEquals,rating-star和rating-empty。在编译之前定义它们否则会出现编译错误。因为我没有运行与您相同的模板的错误,它与模板本身无关,而是与未解析的引用无关。

$(document).ready(function () {
  Handlebars.registerHelper('toLowerCase', function (str) {
  if(str && typeof str === "string") {
    return str.toLowerCase();
  }
  return '';
  });
  Handlebars.registerHelper('ifEquals', function(v1, v2, options) {
  if(v1 === v2) {
    return options.fn(this);
  }
  return options.inverse(this);
  });
  Handlebars.registerHelper('rating-star', function(arg1, options) {
    return options.fn(this);
  });
  Handlebars.registerHelper('rating-empty', function(arg1, arg2, options) {
    return options.fn(this);
  });
  var context = { 
    "website" : { "source" : "test" }, 
    "reviews": [ 
      {"name" : "review1","quote" : "review1 quote","rating" : "1"},
      {"name" : "review2","quote" : "review2 quote","rating" : "5"},
      {"name" : "review3","quote" : "review3 quote","rating" : "3"}
    ] 
  };
	var source   = $("#sourceTemplate").html();
  var template = Handlebars.compile(source);
  var html    = template(context);
  $("#resultPlaceholder").html(html);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script id="sourceTemplate" type="text/x-handlebars-template">
<div class="review-cards__title">
    <img src="/img-src/themev2/theme/{{toLowerCase website.source}}-logo.png" alt="">
</div>
<div class="slick-slider">
    {{#each reviews }}
        <div class="review-card">
            <div class="review-card__name">{{ name }}</div>
            <div class="review-card__quote">
                {{ quote }}
            </div>
            <div class="review-card__stars">
                {{#rating-star rating }}
                    <i class="fa fa-star" aria-hidden="true"></i>
                {{/rating-star}}
                {{#rating-empty rating 5 }}
                    <i class="fa fa-star-o" aria-hidden="true"></i>
                {{/rating-empty}}
            </div>
        </div>
    {{/each}}
</div>
<div class="stats">
    {{#ifEquals website.source "JudgeService" }}
        {{#if judgeservice.dealer_id }}
            {{#if judgeservice.dealer_name }}
                <div id="js-widget-button">
                    <a href="https://www.judgeservice.com/en-gb/car-dealership/name/{{nospace judgeservice.dealer_name }}/" target="_blank" title="{{ judgeservice.dealer_name }} - reviewed on JudgeService.com">
                        {{ judgeservice.dealer_name }} - reviewed on JudgeService.com
                    </a>
                </div>
            {{/if}}
        {{/if}}
    {{/ifEquals}}
    <p>Provided By {{ website.source }}</p>
</div>
</script>
<br/>
<div id="resultPlaceholder">
</div>