我最近从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逻辑,它只是进行一些简单的验证,但是每当您尝试使用这些元素时,它就会爆炸,但是如果您取出验证逻辑,它就可以正常工作。
如果我做错了事情并尝试修复它,我很乐意伸出双手但我老实说不知道问题是什么,因为一切都是孤立的......
答案 0 :(得分:3)
问题是外部模板引擎异步加载模板并最初使用“加载”模板。这意味着您的afterRender
函数会被调用两次。在使用真实模板后,引擎当前无法仅运行afterRender
。我将看看如何添加对它的支持。
您拥有的一些选项:
- afterRender
函数作为第一个参数传递一个元素数组。您可以检查数组以查看它是否包含您的真实元素。
- 另外,在您的电汇代码中,您可以在进行验证调用之前检查您的元素是否存在。
因此,您的函数将被调用两次。您只需要确保第一次不执行任何需要DOM元素存在的代码。
答案 1 :(得分:1)
我是@Grofit在他发布的示例应用程序中使用的外部模板引擎的作者。我已经更新了项目,以便它在一个函数中包装一个afterRender调用,该函数首先检查外部模板源的“已加载”布尔标志是否已设置为true。我发布了示例项目here的更新版本。
瑞安 - 如果有更好的解决方案我会追求,我希望你对此有所反馈。这似乎是最好的选择......答案 2 :(得分:0)
经过多次挖掘后,看起来问题实际上是模板加载框架,因为它们是异步的...而且由于某种原因这个问题没有得到妥善处理,所以淘汰赛会引发事件两次......
理想情况下,我仍然希望能够使用异步加载,但我不确定是否需要更改Knockout或外部绑定......或者两者都可以......