2014-01-28 24 views
1

我有一个使用KnockoutJS的ASP.NET MVC4 SPA web应用程序,这有点尴尬,因为据我了解,当页面最初加载到SPA时通常没有数据直到AJAX调用检索它。当我尝试使用像data-bind="with: myData"这样的属性绑定块中的各种数据时,该节点内的整个DOM被清空,直到myData变为有效,这让我感到紧张,如果某些脚本可能依靠这些元素可用于附加脚本到或某物。页面块在加载过程中消失并重新出现也很糟糕。所以,我设计了with结合,以防止后代绑定,如果该值为空,目前看起来像这样的变化:KnockoutJS“与”绑定在模型可用之前

ko.bindingHandlers.safeWith = { 
    'init': ko.bindingHandlers.with.init, 
    'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     if ((value != undefined) && (value != null)) 
      ko.bindingHandlers.with.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
    } 
}; 

然后,我只是用safeWith而不是with,以确保我没有按DOM”在等待myData被填充时不会消失。

我的问题是:

  1. 这是利用基因敲除SPA的一个共同的问题,如果是这样,它是如何正常处理?
  2. 我处理这个安全问题的方式或者是否有我以某种方式应用重复事件/绑定的风险或我不知道的一些风险?
  3. 我很惊讶我在漫游有关网络学习淘汰赛和相关技术,我没有跑过这个。 倾向于有充分的理由让DOM的部分在它们绑定到的对象为空时消失;我是否试图保持它的错误?

回答

1

我已经实现,通过推迟绑定逻辑,直至观察到其内部具有一个有效值显著改善了我们结果的自定义bindIf绑定处理程序:

ko.bindingHandlers.bindIf = { 
    'init': function (element, valueAccessor) { 
     return { 'controlsDescendantBindings': true }; 
    }, 
    'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     if (!$(element).data("bindIfPassed") && valueAccessor()) { 
      $(element).data("bindIfPassed", true); 
      ko.applyBindingsToDescendants(bindingContext, element); 
     } 
    } 
} 

应用于高级别节点是这样的:

<div data-bind="bindIf: myObservable()"> 
0

我可以看到为什么你不想让带有绑定元素的DOM消失的原因,但它们很少。几乎所有这些都涉及DOM操作,需要一定的时间。例如,在显示视图时,将焦点设置为第一个输入字段。有时候,这种问题的解决方法并不太好,在这种情况下,像你这样的绑定会帮助你很多。

一般来说,

  1. 我想这一定程度上是一个常见的问题。你提到几个 问题:依赖这些元素的脚本:在 一般情况下,我会回应你的脚本是错误的。现在这是一个 有点苛刻,但我确实觉得它有点代码味,如果某个DOM元素不是 可用,那么您的脚本会崩溃。其次,你觉得dom的一部分消失了,并且 重新出现并不是什么好事。在这种情况下,也许你应该 '重置'在你的绑定到 'null'以外的可观察。创建任何对象的“空白”实例,通常将 转换为可观察对象,并使用该对象而不是null,以便DOM 保持不变。如果这不是一个选项,那么你的场景不是 确实是一个绑定的用例(并且你自己的绑定对于这样的场景确实是一个有用的例子)。
  2. 我不完全确定。我试图查看绑定,但由于某种原因,我无法在Knockout代码中找到它。它很容易测试,只需在绑定中设置一个事件绑定,然后改变observable的值几次。看起来有点担心,当值为undefined/null时,从不更新with-binding:我可以想象这很容易导致进一步绑定DOM的错误。
  3. 确实有很好的理由,特别是在单页面应用程序中。我正在用Knockout做一个非常大的应用程序作为SPA。通过正确使用with-binding和清理视图时的视图模型,我可以很容易地管理内存(其中DOM节点是很重要的部分),即使视图缓存在前端。如果我们没有相关数据不存在时卸载DOM节点的机制,应用程序运行速度会非常缓慢。这是一个我非常喜欢的数据驱动方法:所显示的DOM部分是相关的部分,因为数据在那里。
+0

如果您搜索''with''的knockout JS文件(包括引号),您将看到它是通过调用'makeWithIfBinding'创建的。 ''with''只在我的knockout.js版本中出现过一次('knockout-2.2.0.debug.js')。我知道想要移除不适用的DOM部分,但是您是否也必须处理尚未加载模型的DOM的某些部分,但是当页面加载完成时它会被加载?在这些情况下你会遇到这个问题吗? – BlueMonkMN

+0

偶尔遇到它,但我通常在完成加载数据之前避免显示视图。你使用单页面应用程序还是多页面? –

+0

我正在对一个应用程序进行原型设计,我期望每个主要功能都是一个小型SPA。在页面中加载新记录将使用AJAX调用来检索新数据,而不是重新加载整个页面,但导航到另一个函数将加载一个全新的页面。 – BlueMonkMN