Javascript Mustache.js外部模板(不带jQuery)

Javascript Mustache.js外部模板(不带jQuery),javascript,mustache,Javascript,Mustache,我正在编写一个没有jQuery作为依赖项的组件,我希望找到一种方法来加载一个没有jQuery的外部Mustache.js模板。使用jQuery的$.get方法,但我正试图在vanilla JS中实现这一点 我尝试使用XMLHttpRequest并将模板附加到正文中,然后使用我的JSON对其进行水合处理,但是当我的JS尝试将JSON放入模板中时,模板不存在水合作用(无法读取null的innerHTML属性)。这是我的代码(在CoffeeScript中,test.js是胡子模板): 这将在DOM中添

我正在编写一个没有jQuery作为依赖项的组件,我希望找到一种方法来加载一个没有jQuery的外部Mustache.js模板。使用jQuery的
$.get
方法,但我正试图在vanilla JS中实现这一点

我尝试使用
XMLHttpRequest
并将模板附加到正文中,然后使用我的JSON对其进行水合处理,但是当我的JS尝试将JSON放入模板中时,模板不存在水合作用(
无法读取null的innerHTML属性
)。这是我的代码(在CoffeeScript中,
test.js
是胡子模板):

这将在DOM中添加文本
[objecttext]
,而不是将其视为HTML,因此它似乎在评估HTML字符串,而不是将其呈现为HTML字符串

也许有更好的办法。我基本上是尝试将我的应用程序(获取JSON)、mustache.js和模板组合成一个串联的、缩小的文件,作为UI小部件分发

我还研究了一些类似于预编译模板的东西,但感觉很复杂,我无法在这个项目中使用Node

更新 如果我将上述咖啡脚本更新为:

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()
然后,在我的应用程序的相关部分中,它被视为一个字符串,尝试呈现模板:

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

因此,Mustach对待字符串的方式不同于脚本标记中的模板。有没有办法让Mustache将该字符串识别为合法模板?

我找到了如何使用核心JavaScript检索外部模板的方法,该方法的实现灵感来自于。该过程本质上是创建一个新的
div
,使用
XMLHttpRequest
检索模板,并用模板字符串填充创建的
div
innerHTML
。下面是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

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

这里有一个替代方法,使用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));