在由jQueryMobile动态加载的不同页面之间绑定Knockoutjs视图模型

时间:2014-06-12 13:06:56

标签: javascript jquery-mobile knockout.js

然而,我知道这是一个经常被问到的问题,我意识到有三个问题总是模棱两可地回答。

  1. 为什么新页面本身不受约束?
  2. 应该使用什么jQm(jQueryMobile)事件来识别和绑定viewmodel?
  3. 为什么 工作甚至在我执行第1步和第2步后

1 个答案:

答案 0 :(得分:0)

让我尽力回答我的知识

为什么新页面本身不受约束?

  

在绑定视图模型后,Knockoutjs不知道任何内容已加载。当然,跟踪视图模型中呈现的任何更改,但新绑定不能应用于任何外部内容

     

请注意“外部”关键字。 jQm提供使用不同div使用不同pageID在同一文档中维护多个页面,所有这些页面都是固有绑定的,因为knockoutjs不关心页面的jQm呈现。

应该使用什么jQm事件来识别和绑定视图模型?

根据您的要求,使用任何页面事件来执行此操作,但我发现加载事件$('.selector').on('pagecontainerload',function(event,ui){...});非常有用。以下是示例代码。

$('body').on('pagecontainerload', function (event, ui) {
    ko.applyBindings(viewModel, $('#externalPageID')[0]);
});

请注意,externalPageID不是文档的名称,而是文档中的pageID。另请注意,applyBindings方法不会将选择器作为第二个参数,而是将javascript对象作为[0]

为什么即使在我按照步骤1和步骤2

之后它也不起作用

你并不孤单,也不适合我。虽然pagecontainerload事件在页面加载并由jQm增强后触发,但在applyBindings方法可访问页面之前存在非常短的延迟。我不知道为什么,我要求对此提出任何建议或意见。幸运的是,有一个解决方法,下面是一个示例代码

$('body').on('pagecontainerload', function (event, ui) {
    waitToLoad(ui.page[0].id);
});
ko.applyBindings(viewModel); //bind the initial page

function waitToLoad(pageID) {
    if ($('#' + pageID).length > 0) {
        ko.applyBindings(viewModel, $('#' + pageID)[0]); //bind the external page
    }
    else {
        setTimeout(function () { waitToLoad(pageID); }, 100);
    }
}

上面的代码会立即绑定初始页面,每当加载新页面时,它也会被绑定。但是请确保您没有绑定已绑定的页面,情况不太可能,但如果您强制在DOM中重新加载页面,则可能会发生这种情况。确保你手动处理。