如何使用foreach和SignalR使子div不受Knockout JS的约束

时间:2014-04-28 15:39:31

标签: knockout.js signalr

我使用以下博文创建了一个FaceBook样式评论系统:http://techbrij.com/realtime-post-comment-notifications-signalr-knockout

我通过添加/删除隐藏的css类名来添加一种切换commentSection div的方法来扩展功能。如果我只打开一个浏览器实例,它可以很好地工作。但是,当我打开第二个浏览器时,加载该浏览器会将两个浏览器实例注释部分重置为默认值"隐藏"类。有人会有一个关于如何取消绑定敲除绑定的commentSection div的建议,以便该div是受控客户端而不是通过淘汰?以下是基于上述博客文章的缩写代码:

HTML:
...
<ul id="msgHolder" class="post-ul" data-bind="foreach: posts">
     <li class="postHolder post-li"> 
        <div class="postFooter">
           ...
           <a class="toggleCommentSection" href="#" data-bind="click: toggleCommentSection, visible: PostComments().length > 0">View Comment(s)</a>
           <div class="commentSection hidden">
              <ul class="post-ul" data-bind="foreach: PostComments">
                ...
              </ul>
           </div>
        </div>
     </li>
</ul>
...

SCRIPT:
function Post(data, hub, owner) {
   ...
   self.toggleCommentSection = function (item, event) {
        if ($(event.target).next('.commentSection').is(':visible')) {
            $(event.target).next('.commentSection').addClass("hidden");
            $(event.target).html("View Comment(s)");
        }
        else {
            $(event.target).next('.commentSection').removeClass("hidden");
            $(event.target).html("Hide Comment(s)");
        }
    }
}

1 个答案:

答案 0 :(得分:0)

问题不在于它仍然受到敲门声的束缚。问题是,如果有人连接,所有帖子都会再次加载。

来自PostHub:

// GET api/WallPost
public void GetPosts()
{
    ...
    Clients.All.loadPosts(ret);
}

我认为这应该是Clients.Caller.loadPosts(ret)。但除此之外,这意味着如果有人调用GetPosts(),则会在所有客户端上调用函数loadPosts(data)

self.hub.client.loadPosts = function (data) {
    var mappedPosts = $.map(data, function (item) { return new Post(item, self.hub); });
    self.posts(mappedPosts);
}

这将使用新帖子替换帖子。这反过来会再次呈现<ul id="msgHolder" class="post-ul" data-bind="foreach: posts" />,这意味着你失去了隐藏状态。

为了防止这种情况发生,您还应该使用knockoutjs来记住隐藏状态:

向您的客户端添加属性发布:

self.commentsHidden = ko.observable(true);

HTML:

<ul id="msgHolder" class="post-ul" data-bind="foreach: posts">
     <li class="postHolder post-li"> 
        <div class="postFooter">
           ...
           <a class="toggleCommentSection" href="#" data-bind="
               click: toggleCommentSection, 
               visible: PostComments().length > 0, 
               text: commentsHidden() ? 'View Comment(s)' : 'Hide Comment(s)'
               "></a>
           <div class="commentSection" data-bind="css: { hidden: commentsHidden }">
              <ul class="post-ul" data-bind="foreach: PostComments">
                ...
              </ul>
           </div>
        </div>
     </li>
</ul>

<强> toggleCommentSection:

self.toggleCommentSection = function() {
    self.commentsHidden(!self.commentsHidden());
}

欢迎来到Knockout的世界!