knockoutjs afterRender问题在版本2中,在版本1.2.X中不明显

时间:2012-01-07 22:59:09

标签: dom knockout.js templating

我最近从KnockoutJS 1.2.1将现有项目更新为KnockoutJS 2.0(尽管我是使用之前的版本开始的)。自更新以来,我注意到afterRender似乎在元素实际完全在html中之前被触发。

我做了一些环顾四周,根据围绕这个领域的一些其他问题,这似乎是预期的行为:

Why are template divs showing as ":hidden" in afterRender?

问题在于Jquery Validate,我将一些规则应用于元素,它告诉我元素不存在。奇怪的是,这曾经在1.2.1中运行良好。我不确定这是否是因为在以前的版本中对afterRender的处理方式不同,或者对一般原生模板系统的更改导致它的行为不同......

如果有变化或者这是预期的行为,有什么方法可以知道模板元素何时实际输入了html应该在哪里?我知道加载的元素是通过afterRender回调参数传回来的,但是在这个阶段使用这些元素进行Dom操作是否安全?

修改

我已经把我的具体问题放在一个例子中: Example project showing issue

如果您查看每个模板的afterRender逻辑,它只是进行一些简单的验证,但是每当您尝试使用这些元素时,它就会爆炸,但是如果您取出验证逻辑,它就可以正常工作。

如果我做错了事情并尝试修复它,我很乐意伸出双手但我老实说不知道问题是什么,因为一切都是孤立的......

3 个答案:

答案 0 :(得分:3)

问题是外部模板引擎异步加载模板并最初使用“加载”模板。这意味着您的afterRender函数会被调用两次。在使用真实模板后,引擎当前无法仅运行afterRender。我将看看如何添加对它的支持。

您拥有的一些选项: - afterRender函数作为第一个参数传递一个元素数组。您可以检查数组以查看它是否包含您的真实元素。

- 另外,在您的电汇代码中,您可以在进行验证调用之前检查您的元素是否存在。

因此,您的函数将被调用两次。您只需要确保第一次不执行任何需要DOM元素存在的代码。

答案 1 :(得分:1)

我是@Grofit在他发布的示例应用程序中使用的外部模板引擎的作者。我已经更新了项目,以便它在一个函数中包装一个afterRender调用,该函数首先检查外部模板源的“已加载”布尔标志是否已设置为true。我发布了示例项目here的更新版本。

瑞安 - 如果有更好的解决方案我会追求,我希望你对此有所反馈。这似乎是最好的选择......

答案 2 :(得分:0)

经过多次挖掘后,看起来问题实际上是模板加载框架,因为它们是异步的...而且由于某种原因这个问题没有得到妥善处理,所以淘汰赛会引发事件两次......

理想情况下,我仍然希望能够使用异步加载,但我不确定是否需要更改Knockout或外部绑定......或者两者都可以......