Knockout,JQMobile和生成可折叠集似乎无法正常工作。

5

我已经查看了许多示例,但没有一个与我尝试做的完全相同。

我所拥有的基本上可以工作,但它并不完全正确。

这里有一个演示来说明问题。

http://jsfiddle.net/5yA6G/4/

注意顶部的设置可以正常工作,但是它是静态定义的。
底部的设置(Tom、Steve、Bob)“基本上”可以工作,但标题元素最终既出现在可折叠的标题中,也出现在被隐藏的可折叠部分中。
似乎我必须做错了什么,但我还没有找出来。
有什么想法吗?
2个回答

6

仅供参考,对于任何遇到此问题的人,后来发现这至少在事后看起来有些显然。

Knockout内置的“匿名”模板在许多情况下都很好用,但是在JQMobile中,它可能有些古怪。

这是因为JQMobile会在页面加载时调整匿名模板的内容,就像它处理所有其他内容一样。

然后,稍后当您使用knockout的ApplyBindings函数时,knockout将添加适用的元素,就像它应该做的那样。正如许多帖子和答案所暗示的那样,您必须通过类似以下方式对新创建的元素调用collapsible()。

$("div[data-role='collapsible']").collapsible({refresh: true});

没有任何问题。然而,如果JQM已经应用了格式,则匿名模板已经被JQM“渲染”,因此通过调用可折叠的方式再次呈现它会导致所有种类的奇怪结果,包括重复标题、嵌套可折叠等。

对我来说解决方案是使用Knockout的“命名模板”功能,只需将用于呈现可折叠元素的模板放入一个<script type="text/html">标签中,像这样:

<script type="text/html" id="alarm-template">
    <div data-role="collapsible" data-collapsed="true" data-collapsed-icon="arrow-d" data-expanded-icon="arrow-u" data-enhance="false">
        <h3 data-bind="text:name"></h3>
        <p>The content here</p>
        <p data-bind="text: name"></p>
    </div>
</script>               

这样做可以防止JQM在页面加载时“渲染”模板元素,因此当它们实际生成时,它们将被正确地呈现。
编辑:上述方法对于不在可折叠集中的可折叠内容正常工作,但是,如果它们在一个集合中,则我发现元素的样式(特别是用于指示属于集合的角落圆角)无法正常工作。
据我所知,存在两个问题:
第一个问题是仅触发“创建”并不能实际刷新集合中所有可折叠内容的样式。要做到这一点,您需要执行...
$("div[data-role='collapsible-set']").collapsibleset('refresh');

但是,还有一个更糟糕的问题。JQM会将集合中的最后一项标记为“最后一项”。这个事实然后被用来确定在展开/折叠最后一项时如何进行样式设置。
由于Knockout实际上不会重建整个集合(为了提高速度),每次调用刷新方法时,JQM都会忠实地将最后一项标记为“最后一项”,但从不删除先前项目上的标记。因此,如果您从空列表开始,每个项目都会被标记为“last”,并且由于此原因导致样式失败。
我在github的问题报告中详细介绍了解决方法。 https://github.com/jquery/jquery-mobile/issues/4645

4
我实际上发现了一个更简单的方法来完成这个操作:

  1. Set up your foreach binding as you normally would for me it looked like this

    <div data-bind="foreach: promotions">
    
        <h3 data-bind="text: Title"></h3>
            <p>Creator:<span data-bind="text: Creator"></span></p> 
            <p>Effective Date:<span data-bind="text: EffectiveDate"></span></p>
            <span data-bind="text: Description"></span>
            <a data-bind="text: ButtonText, attr: {href: ButtonLink}"></a>
    

  2. Wrap that in a div with class="collapsible like so

    <div data-role="collapsible-set" data-bind="foreach: promotions">
    
    <div class="collapsible">
        <h3 data-bind="text: Title"></h3>
            <p>Creator:<span data-bind="text: Creator"></span></p> 
            <p>Effective Date:<span data-bind="text: EffectiveDate"></span></p>
            <span data-bind="text: Description"></span>
            <a data-bind="text: ButtonText, attr: {href: ButtonLink}"></a>
    

  3. Apply the collapsible widget via jquery mobile after you do your binding like so:

    $(document).ready(function () {
        ko.mapping.fromJS(data, dataMappingOptions, PromotionViewModel.promotions);
        ko.applyBindings(PromotionViewModel);
        $('.collapsible').collapsible();
    });
    
  4. For a collapsible set the same idea can be applied just set the class="collapsible-set" on your foreach div. Hope this helps


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接