将knockoutjs连接到已填充的DOM元素

Aar*_*ell 9 knockout.js

我正在开发一个页面,它是一个ASP.NET MVC3应用程序的服务器,我想在其中使用KnockoutJS.

在View上我已经传递了一个填充的模型(我正在转换为KnockoutJS viewModel),我想构建一些DOM服务器端.这似乎是合乎逻辑的,因为我已经有了生成初始HTML的对象,它将为用户提供更好的体验,因为页面加载和DOM填充之间不会有延迟(这也意味着我有非基本功能) -JavaScript客户端).

做了一些研究后,我假设我需要创建一个自定义,bindingHandler所以我创建了这个:

ko.bindingHandlers.serverForEach = {
    init: function() { /* no-op */ },
    update: function() {
        //call off to the built in loop handler
    }
};
Run Code Online (Sandbox Code Playgroud)

所以我的想法是我创建了一个处理程序,它在init阶段中没有做任何事情(因为已经填充了DOM),并且在update阶段I中我只是插入新值.我想利用内置的模板,这也是一个通用的解决方案.

问题是在这种情况下一切都崩溃了.如果init什么都不做,则update失败,因为作为最后一个参数进入的bindingContext似乎是错误的,如果我包含init它将破坏现有的HTML.

任何人都试过这个/知道我应该做些什么来支持这种情况,或者它与你能做什么/应该做的太远了?

此外,我不希望为服务器生成的HTML提供单独的DOM元素而不是Knockout HTML.

mad*_*kay 8

我想我明白你的问题是什么.您希望最初为非js用户填充标记,并在绑定到KO时简单地覆盖它.

对于像文本这样的简单绑定,这不是一个问题,只需在服务器的标记中包含data-bind属性,或者在运行时包含,然后就可以了.对于模板foreach绑定事情有点困难,因为它会在绑定时附加值.

这是一个描述上述场景的jsfiddle,并演示了下面的解决方案.这有点基础,但应该让你开始.

基本思想是清除init上的元素,然后将其余部分委托给现有的模板绑定.

ko.bindingHandlers.serverForEach = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        // clear the list first
        $(element).children().remove();
    },
    update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
        ko.bindingHandlers['template'].update(element, valueAccessor, allBindingsAccessor, viewModel);
    }
};
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.