2013-07-29 53 views
2

這是一個小衆情況,但我有一個簡單的聊天室風格的場景。如何附加到淘汰賽foreach中的現有元素,而不是創建新元素

所以會有一個可觀察的聊天條目數組(這可能會限制爲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 --> 

而且目前每個條目,將添加一個新的聊天入口,這是很好的,看起來像這樣:

The existing chat system

然而,有如果下一篇文章是由同一個人發佈的話,那麼現在就需要添加到現有的聊天記錄中,就像這樣(原諒可怕的繪畫作業)。

The required chat system

而且我不知道如何在淘汰賽做到這一點......我想,我可能做一個AfterRender階段,並檢查它是否是一樣的前一個條目海報然後刪除所有創建並找到以前的條目和使用jquery或東西只是追加元素,但這感覺非常黑客,即時通訊手動操縱dom。

那麼有沒有的方法來解決這個問題?

== ==編輯

只是爲了澄清一些事情,目前我一直追加到,每當一個新條目來在觀察的陣列,但有是剛剛重新創建陣列的每一個參數時間會有新的東西出現,因爲這會簡化一些事情,但不確定這樣做的可見影響與僅追加單個條目的效果。

目前在截止點之後有50個緩衝區,所以主數組存儲大約100個,然後將允許另一個50%(最多150個入口),然後一旦它結束,它將切斷最後的50個入口並重新創建陣列,因此再次有100個條目,則用戶可以回頁面查看以前的條目。所以這減少了娛樂,但聽起來可能最終變得更復雜一些。所有進來的聊天記錄本地存儲在本地存儲中,因此無需服務器即可快速分頁,因此丟失了聊天數據。

+1

創建'ko.computed'該工程對'ChatEntries'和人員的名字確實在groupping 。我已經在這裏回答了類似的問題:http://stackoverflow.com/questions/17882964/knockout-generate-for-an-array-of-15-items-3-sections-and-5-articles-for-each- se/17885378#17885378 – nemesv

+1

所以,你知道,任何DOM操作都不會呈現,直到一個線程退出。所以除非你使用'setTimeout',這不會是一個問題。如果您在沒有正確轉換的情況下添加/刪除元素,則屏幕可能會閃爍。 – FakeRainBrigand

回答

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 --> 

看一看小提琴here

這可以用計算字段也可以做,但它需要一些JavaScript代碼,併爲你改變你的模型。此解決方案需要而不是隻改變爲html

+0

我正在考慮做些* *這樣的事情,因爲我做了一個方法,該方法使用索引並返回true或false,指示下一個用戶是否與上一個用戶相同,問題是在您的示例中,就像我的每一次迭代都會添加一個新的聊天條目div,並且這會在下一個聊天條目進入時破壞它,先前的條目已經被包含爲一個單獨的條目,所以您不得不回到上一個條目並修改它,這意味着手動DOM操作。這是假設我正在添加到數組並且從不重新創建 – Grofit

1

不會更改數組以適合您的視圖更多黑客行爲?對於操作DOM淘汰賽有bindingHandlers。所以也許自定義綁定將是你正在尋找。只需將currentUser與previousUser進行比較,然後決定將span擴展到以前的條目或創建新的。沒有jQuery,純javascript。或者jQuery,如果你想用新的消息到達效果。您甚至可以提供模板作爲參數,以便您的聊天可以有供用戶選擇的主題。

綁定也已經提供了很多信息: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

+0

取決於您如何看待它,因爲視圖模型應該代表視圖,並且只是視圖需要的數據的一個控制點。所以可以說視圖模型中的數據應該直接表示視圖的期望值。然而,因爲這是那些不符合標準的古怪用法之一,所以在這種情況下,將數據保持爲一個數組就像是它的原樣,並且在視圖中的某處,就像您說的那樣代表數據以不同的方式。 – Grofit

+0

好點。有趣的問題你在這裏。我會跟隨這個問題,也許我會學到更多東西。 –

+0

似乎並不存在*不錯的方式,迄今爲止最好的方式似乎正在改變數據的存儲方式,並在每次新消息進入時重新創建對象,因此成爲一個分組列表。任何其他可能的方式似乎都有視角模型支配dom的使用和玩它不應該做的事情......就像你希望有人會來,並給我們一些知識的寶庫。 – Grofit