Mustache.js 外部模板(没有 jQuery)
Mustache.js external template (without jQuery)
我正在编写一个没有 jQuery 作为依赖项的组件,我希望找到一种方法来加载没有 jQuery 的外部 Mustache.js 模板。使用 jQuery 的 $.get
方法 appears to work,但我正在尝试在 vanilla JS 中执行此操作。
我尝试使用 XMLHttpRequest
并将模板附加到正文,然后 然后 用我的 JSON 补水,但是当我的 JS 尝试将 JSON 放入模板中,模板不是用来水合的 (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 和受 this SO answer 启发的实现来检索外部模板。该过程实质上是创建一个新的 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
使用您的 JSON 数据 resp
呈现模板。
这是 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));
我正在编写一个没有 jQuery 作为依赖项的组件,我希望找到一种方法来加载没有 jQuery 的外部 Mustache.js 模板。使用 jQuery 的 $.get
方法 appears to work,但我正在尝试在 vanilla JS 中执行此操作。
我尝试使用 XMLHttpRequest
并将模板附加到正文,然后 然后 用我的 JSON 补水,但是当我的 JS 尝试将 JSON 放入模板中,模板不是用来水合的 (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 和受 this SO answer 启发的实现来检索外部模板。该过程实质上是创建一个新的 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
使用您的 JSON 数据 resp
呈现模板。
这是 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));