【问题标题】:Mustache.js external template (without jQuery)Mustache.js 外部模板(没有 jQuery)
【发布时间】:2015-06-21 00:42:41
【问题描述】:

我正在编写一个没有 jQuery 作为依赖项的组件,我希望找到一种方法来加载没有 jQuery 的外部 Mustache.js 模板。使用 jQuery 的 $.get 方法 appears to work,但我正在尝试在 vanilla JS 中执行此操作。

我尝试使用XMLHttpRequest 并将模板附加到正文,然后然后用我的 JSON 水合它,但是当我的 JS 尝试将 JSON 放入模板时,模板不是t 需要补水 (cannot read property innerHTML of null)。这是我的代码(在 CoffeeScript 中,test.js 是小胡子模板):

req2 = new XMLHttpRequest()
req2.onload = ->
  foo = document.getElementById('thatsmyjam')
  templ = document.createTextNode(this.responseText)
  foo.insertAdjacentHTML('beforeEnd', templ)
req2.open('GET', 'test.js', { async: false})
req2.responseType = 'document'
req2.send()

这会在 DOM 中添加文字文本 [object Text] 而不是将其视为 HTML,因此它似乎是在评估 HTML 字符串而不是渲染它。

可能有更好的方法。我基本上是在尝试将我的应用程序(获取 JSON)、mustache.js 和模板组合成一个连接的、缩小的文件,以作为 UI 小部件进行分发。

我还研究了Hogan.js 之类的东西来预编译模板,但感觉很复杂,而且我无法在这个项目中使用 Node。

更新

如果我将上面的 CoffeeScript 更新为:

req2 = new XMLHttpRequest()
req2.onload = ->
  foo = document.getElementById('thatsmyjam')
  window.templ = document.createTextNode(this.responseText)
  foo.insertAdjacentHTML('beforeEnd', templ)
req2.open('GET', 'test.js', { async: false})
req2.send()

然后它在我的应用程序的相关部分中被视为一个字符串,试图呈现模板:

populateDom: =>
    self = @
    @request.addEventListener 'loadend', ->
      if @status is 200 && @response
        resp = self.responseAsJSON(@response)
        # here, window.templ is a string returned from the XMLHttpRequest above,
        # as opposed to an actual "template", so Mustache can't call render with it.
        rendered = Mustache.render(window.templ, resp)
        document.getElementById('thatsmyjam').innerHTML = rendered
        self.reformatDate(resp)

因此,Mustache 对待字符串的方式与处理脚本标签内的模板不同。有没有办法让 Mustache 将该字符串识别为合法模板?

【问题讨论】:

    标签: javascript mustache


    【解决方案1】:

    我想出了如何使用受this SO answer 启发的实现使用核心 JavaScript 检索外部模板。该过程本质上是创建一个新的div,用XMLHttpRequest 检索模板,并用模板字符串填充创建的divinnerHTML。这是 CoffeeScript 中的实现:

    class TemplateManager
      templateUrl: '/path/to/template.mustache'
      retrieveTemplate: ->
        req = new XMLHttpRequest()
        req.onload = ->
          div = document.createElement('div')
          div.innerHTML = this.responseText
          window.mustacheTemplate = div
        req.open('GET', @templateUrl, { async: false})
        req.send()
    

    然后你可以调用

    rendered = Mustache.render(window.mustacheTemplate.innerHTML, resp)
    document.getElementById('YOURDIV').innerHTML = rendered
    

    使用您的 JSON 数据 resp 呈现模板。

    【讨论】:

      【解决方案2】:

      这是 2018 年使用 fetch 并行获取数据和模板的替代方案:

      // Get external data with fetch
      const data = fetch('data.json').then(response => response.json());
      
      // Get external template with fetch
      const template = fetch('template.mst').then(response => response.text());
      
      // wait for all the data to be received
      Promise.all([data,template])
      .then(response => {
      
          resolvedData = response[0];
          resolvedTemplate = response[1];
      
          // Cache the template for future uses
          Mustache.parse(resolvedTemplate);
      
          var output = Mustache.render(resolvedTemplate, resolvedData);
      
          // Write out the rendered template
           return document.getElementById('target').innerHTML = output;
      
      }).catch(error => console.log('Unable to get all template data: ', error.message));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-16
        • 1970-01-01
        • 2013-01-07
        • 2011-09-06
        • 2011-05-17
        • 1970-01-01
        相关资源
        最近更新 更多