解锁模板和复杂Web应用程序中的唯一ID导致问题

时间:2014-06-20 13:23:23

标签: javascript templates knockout.js

Knockout模板系统非常棒,但是在一个由ajax加载的几个单独的上下文(“views”)的Web应用程序中,会出现一个问题:

  

模板依赖于ID

这意味着如果我有机会在一个视图上有一个同名的模板,而这个模板在之前加载的另一个视图中仍然存在于webapp上下文中,则敲除(因为浏览器执行此操作)将采用第一个匹配的#templateId元素

在我们的webapp上,我们删除了所有元素的ID,当它真正需要使用时,它是一个javascript被确定为没有重复的ID。

  

有些视图可以在应用的生命周期内多次加载,所以   没有,我们不能在我们的团队成员中说“只是检查ID是否已经在使用HTML代码之前”。

我们唯一能做的就是检查是否加载了特定模板,如果没有加载异步,则应用绑定。但为了简单起见以及我们现在设置项目的方式,我们不能应用类似AMD的依赖管理器。

问题

  • 是否可以直接指定对模板的DOM引用?

    data-bind="template:function(){ return $('yourSelectorToTheTemplate')[0]; }"

我看起来是淘汰代码,这很奇怪,因为我们有这个:

templateDocument = templateDocument || document;
        var elem = templateDocument.getElementById(template);
        if (!elem)
            throw new Error("Cannot find template with ID " + template);
        return new ko.templateSources.domElement(elem);

这意味着它确实使用了DOM元素,那么如果我们已经拥有ID,为什么被迫为它提供ID?

  • 我们如何检索动态应用的IDtemplate,即调用另一个动态应用的ID(例如递归调用自身的模板)?

从绑定处理程序设置ID可能是错误的:它可能在引用其他数据绑定元素之后设置ID,但它必须更简单。

1 个答案:

答案 0 :(得分:0)

目前找到的最佳解决方案:

  1. 将模板(脚本元素)放在html视图的顶部。
  2. 使用初始化的bindingHandler(我在下面的例子中看到我称之为“init”)来设置脚本元素的ID
  3. 将该ID存储在$ root上下文中,以便其他元素可以重用
  4. 结果如下:

    <script type="text/html" data-bind="init: function(){ $rawData.folderItemTemplate = functionThatSetsAndReturnsUniqueId($element, 'folderItemTemplate'); }">
            <li> 
                Some item
                <ul data-bind="template: { name: $rawData.folderItemTemplate, foreach: children }"></ul>
            </li>
        </script>
    

    如您所见,我们可以使用此模板绑定模板:{name:$ rawData.yourPropertyName,foreach:...}