2

这是一个小众案例,但我有一个简单的聊天室风格场景。

所以会有一个可观察的聊天条目数组(这可能会限制为 100 个条目,这些条目会被分页以保持良好的性能)。

所以当前的 foreach 看起来像:

<!-- ko foreach: ChatEntries -->
<div class="chat-entry">
    <img class="entry-sender"></span>
    <span class="entry-content" data-bind="html: Content"></span>
</div>
<!-- /ko -->

目前,它会为每个条目添加一个新的聊天条目,这很好,看起来像这样:

现有的聊天系统

但是,如果下一个帖子是由同一个人发布的,现在需要仅附加到现有的聊天条目,就像这样(原谅可怕的油漆工作)。

所需的聊天系统

而且我不知道如何在淘汰赛中做到这一点......我在想我可以做一个 afterRender 并检查它是否与以前的条目海报相同然后删除所有创建的 dom 并找到以前的条目并使用 jquery或者只是附加元素,但这感觉非常hack-ish,因为我手动操作dom。

那么有什么好的方法可以解决这个问题吗?

== 编辑 ==

只是为了澄清一些事情,目前我总是在有新条目进入时附加到可观察数组,但是有一个论点是每次有新条目进入时都重新创建数组,因为这会简化事情位,但不确定这样做与仅附加单个条目的明显影响。

目前在截止点之后有一个 50 的缓冲区,所以主数组存储大约 100,然后将允许另外 50%(最多 150 个条目),然后一旦超过,它将切断最后 50 个条目并重新创建数组,所以再次有 100 个条目,然后用户可以翻页查看以前的条目。所以这减少了娱乐性,但听起来可能最终会变得更加复杂。所有进来的聊天都本地存储在localstorage中,所以不需要服务器就可以快速分页,所以不用担心丢失聊天数据。

4

2 回答 2

1

您可以将几个敲除功能if与该功能一起使用$index()

不是最优雅的解决方案,但它很简单并且可以完成工作。

<!-- ko foreach: ChatEntries -->
<div class="chat-entry">
    <!-- ko if: $index() === 0 -->  //first item does not have a previous
        <span class="entry-sender">img</span>
        <span class="entry-content" data-bind="html: Content"></span>
    <!-- /ko -->
    <!-- ko if: $parent.ChatEntries()[$index()-1]-->    //check if previous is same user
        <!-- ko if: user !== ($parent.ChatEntries()[$index()-1].user)-->    
        <span class="entry-sender">img</span>
        <span class="entry-content" data-bind="html: Content"></span>
        <!-- /ko -->
        <!-- ko if: user === ($parent.ChatEntries()[$index()-1].user)-->    
        <span class="entry-content" data-bind="html: Content"></span>
        <!-- /ko -->
    <!-- /ko -->
</div>
<!-- /ko -->

看看这里的小提琴

这也可以通过计算字段来完成,但它需要一些 javascript 代码并让您更改模型。此解决方案只需要更改 html

于 2013-07-30T07:34:13.310 回答
1

更改数组以适应您的视图会不会更hack-ish?用于操作 DOM 敲除具有 bindingHandlers。所以也许自定义绑定就是你要找的。只需将 currentUser 与 previousUser 进行比较,然后决定将 span 附加到上一个条目或创建新条目。没有 jQuery,纯 JavaScript。或者 jQuery,如果你想用新消息到达的效果来做。您甚至可以提供模板作为参数,以便您的聊天可以有主题供用户选择。

Bindings 也已经提供了很多信息:http ://www.knockmeout.net/2011/07/another-look-at-custom-bindings-for.html

IMO 这可能是最干净的解决方案,数据在模型中,视图在视图中。您的主要 HTML 是干净的:

<!-- ko foreach: ChatEntries as chatEntry -->
    <div class="chat-entry" data-bind="yourCustomChatBinding: chatEntry"></div>
<!-- /ko -->

只是一个想法:如果附加数据,上面的代码将创建空 div。KO虚拟元素:

<!-- ko foreach: ChatEntries as chatEntry -->
    <!-- ko yourCustomChatBinding: chatEntry -->
<!-- /ko -->

虚拟元素有一些不错的 API 可以使用: http: //knockoutjs.com/documentation/custom-bindings-for-virtual-elements.html

于 2013-07-30T12:38:40.977 回答