我有一个页面,它使用Kendo MVVM方法处理两个不同的元素,一个提供文件搜索结果,另一个提供文档上传工具。
我遇到的问题是两个元素都使用的更改事件 - 似乎当一个控件触发一个更改事件时,它会被另一个控件拾取,然后尝试处理事件并将其传递,此时它由第二个控件的 change 处理程序拾取,该处理程序处理它并将其传递给第一个控件的 change 处理程序。正如您所料,在此周期重复大约1500次之后,我看到Uncaught RangeError: Maximum call stack size exceeded
消息,因为JavaScript引擎内存不足。
起初我认为问题是第二个模型的容器包含在第一个模型中,但即使它们在页面上完全分离,似乎问题仍然显示出来,所以现在我想知道是否问题与页面的全局事件有关。
似乎我在事件处理程序中尝试stopPropagation
或stopImmediatePropagation
- 甚至将事件设置为完全无效 - 对此行为没有任何影响。跟踪调用堆栈我可以看到它循环通过Kendo的trigger
调用然后通过我的对象上的事件绑定和jQuery的调度循环导致它返回到Kendo,在那里它触发另一个可观察对象上的事件处理程序。 p>
删除我的绑定不会影响问题,change
事件仍然以同样的方式在Kendo和jQuery之间来回反弹,它只是没有运行我的代码。
答案 0 :(得分:0)
这里的答案并不是剑道本身的直接结果,所以在我设定它时,很难回答这个问题。
在引发此错误的Observable容器中,我使用Isotope进行布局。我错过的一步是我有这样的关系:
Parent [Observable]
-> Container
-> Child
-> Child
-> Child
Isotope
为聚会带来的一件事是,对于子集合中的每个项目,它都会添加对其父对象的引用。
如果孩子Observable
创建了这样的结构:
Parent [Observable]
-> Container <--┐
-> Child ---|
-> Child ---|
-> Child ---┘
这是将事件从子节点传播到父节点的理想情况,但由于所讨论的属性是由相关库自动添加的,因此很难进行故障排除。
解决方案是从Observable模型中删除Container
层 - 它不需要在更改时触发任何内容,因此我将其包装在一个简单的getContainer()
闭包中并在我到处使用以前用它作为财产。这保护它免受Observable
对象的攻击,打破循环引用而不会损害功能。
就我所知,发起事件是一个DOM change
事件而不是剑道自己的事件之一,也可能是相关的。使用自定义Kendo命名空间可能可以避免这个问题,但这在复杂的应用程序中会发生重大变化,并且会导致很多副作用。