正如Raphael所暗示的,事实证明,当Magento通过XHR(即ajax)请求下载其KnockoutJS模板时,它还会通过一些自定义解析例程传递它们,这些例程会查找许多自定义标签和属性。
此自定义解析由Magento_Ui/js/lib/knockout/template/renderer
RequireJS模块完成。该模块的源代码设置了许多要搜索的默认标记和属性。还有其他模块可以向此渲染器添加其他标签和属性。例如,以下
#File: vendor/magento/module-ui/view/base/web/js/lib/knockout/bindings/scope.js
renderer
.addNode('scope')
.addAttribute('scope', {
name: 'ko-scope'
});
将<scope/>
标记和scope
属性(<div scope="...">
)添加到可分析属性的列表中。
是好像基本思想是将这些标签转换和属性为本地敲除“无标签”模板块。例如,以下Magento KnockoutJS模板
<each args="data: elems, as: 'element'">
<render if="hasTemplate()"/>
</each>
转换为以下本地KnockoutJS代码
<!-- ko foreach: {data: elems, as: 'element'} -->
<!-- ko if: hasTemplate() --><!-- ko template: getTemplate() --><!-- /ko --><!-- /ko -->
<!-- /ko -->
对于我来说,这种翻译的确切规则仍然不清楚,因为其中的代码Magento_Ui/js/lib/knockout/template/renderer
是间接的,似乎它们可以在标签之间更改,在属性之间更改。
我已经弄懂了以下代码片段,可以下载Magento KnockoutJS模板,并将其转换为本地的KnockoutJS代码。
jQuery.get('http://magento-2-1-0.dev/static/adminhtml/Magento/backend/en_US/Magento_Ui/templates/collection.html', function(result){
var renderer = requirejs('Magento_Ui/js/lib/knockout/template/renderer')
var fragment = document.createDocumentFragment();
$(fragment).append(result);
//fragment is passed by reference, modified
renderer.normalize(fragment);
var string = new XMLSerializer().serializeToString(fragment);
console.log(string);
})
至于Magento为何会这样做-我的猜测是希望KnockoutJS的注释模板具有某种语法高亮性和可读性,但从不排除更多类似于Mallory的理由。