Angular.js - 如何使用实时s​​ocket.io数据更新

时间:2015-06-09 06:09:18

标签: angularjs socket.io

所以我有一个应用程序,它使用socket.io实时更新数据并使用Angular JS显示它。

我在多个ng-repeats中显示数据(注释),使用'track by'确保在引入最新数据时忽略重复项。我也使用LimitTo仅显示一定数量的一次评论,LimitTo是动态的,当用户点击按钮时会增加。

HTML

<div ng-controller="CommentsController" >
<!-- Comment Repeater Starts Here -->
<div ng-repeat="comment in comments | limitTo: limit track by comment.id" >
    {{ comment.comment }}

    <!-- Nested Reply Comments Start Here -->
    <div ng-repeat="reply in comment.replies | limitTo: comment.limit track by reply.id" >
        <div class="comment-text" >
            {{ reply.comment }}
        </div>
    </div>
    <a href="#" ng-click="increaseReplyLimit(comment, comment.limit)" ng-show="hasMoreComments(comment.replies, comment.limit)" >View More Replies</a>
</div>
<a href="#" ng-click="increaseLimit(limit)" ng-show="hasMoreComments(comments,limit)" >View More Comments</a>

我的第一个ng-repeat工作得非常好,因为我将LimitTo分配给范围内的变量,当我通过Socket.io引入新数据时,该变量不受影响。 对于我的嵌套ng-repeat,我使用comment.limit作为LimitTo的变量,每次通过socket.io引入新数据时都会被覆盖。(新数据)有一个默认的comment.limit - 我尝试将此空白留下,但没有任何显示)。

Angular

app.controller('CommentsController', function ($scope,socket,$http,$location) {

// fetching the latest comments from the API location
$http.get( $url + 'comments').success(function(comments) {
    if (comments) {  
        $scope.comments = comments;
    }
});

// updating comments via socket.io
socket.on('comment.update', function (data) {
    $scope.comments = JSON.parse(data);
});

$scope.limit = 2;

$scope.hasMoreComments = function(comments, limit) {

    if (typeof comments != "undefined" && comments != "false") {

        var $commentLength = comments.length;

        if ($commentLength > limit) {
            return true;
        } 
        return false;
    }
    return false;   
}

$scope.increaseLimit = function(limit) {
    $scope.limit = $scope.limit + 2;
}

$scope.increaseReplyLimit = function(comment, limit) {
    comment.limit = parseInt(limit) + 2;
}

});

当我从socket.io引入新数据时,如何防止每个嵌套重复的当前限制被覆盖?

我已经尝试对旧数据和新数据进行深度合并(想法是更新新数据中的嵌套限制以反映当前的嵌套限制)。但是,当我这样做时,Angular完全忽略了新限制,不再对嵌套注释强制执行任何限制。

引入数据的结构

[
{
    "topics": [
        {
        "id": 75,
        "topic": "test",
        "approved": 1,
        "created_at": "-0001-11-30 00:00:00",
        "updated_at": "-0001-11-30 00:00:00",
        "slug": "test",
        "blurb": null
        }
    ],
    "id": 849,
    "user_id": 80,
    "news_id": 9,
    "context": "Test News Article 1",
    "comment": "<p>test comment 4</p>",
    "origin": "Test",
    "origin_url": "http://localhost:8000/news/test-news-article-1",
    "author": "omurphy27",
    "author_url": null,
    "votes": 0,
    "created_at": "2015-06-08 22:36:53",
    "updated_at": "2015-06-08 22:36:53",
    "approved": 1,
    "slug": "test-comment-116",
    "original": 1,
    "parent_id": null,
    "username": "omurphy27",
    "limit": 2,
    "voted": false
}

用这个把我的头撞在墙上已经有一段时间了,任何帮助都非常感谢。

1 个答案:

答案 0 :(得分:0)

我最终为嵌套的回复限制创建了一个单独的数组,并将其附加到作用域(而不是在socket.io实时引入和更新的数据对象中具有这些限制)

请参阅我下面的更新角度代码

app.controller('CommentsController', function ($scope,socket,$http,$location) {

// fetching the latest comments from the API location
$http.get( $url + 'comments').success(function(comments) {
    if (comments) {  
        $scope.comments = comments;
    }

    // populate my separate array for reply limits
    $scope.populateLimits(comments.length, 4);
});

$scope.populateLimits = function(limitLength, limit) {

    var limits = [];
    for (var i = limitLength - 1; i >= 0; i--) {
        limits[i] = limit;
    };

    $scope.limits = limits;
}

// updating comments via socket.io
socket.on('comment.update', function (data) {

    if (data.length > $scope.comments.length) {
        var difference = data.length - $scope.comments.length; 

        // increment the limits array by however 
        // many new comments are pulled in by socket.io
        $scope.incrementLimits(difference);
    }

    $scope.comments = JSON.parse(data);
});

$scope.incrementLimits = function(difference) {

    var newLimits = $scope.limits;
    for (var i = 0; i < difference; i++) {
        newLimits.unshift(2);
    };

   $scope.limits = newLimits;
}

$scope.limit = 2;

$scope.hasMoreComments = function(comments, limit) {

    if (typeof comments != "undefined" && comments != "false") {

        var $commentLength = comments.length;

        if ($commentLength > limit) {
            return true;
        } 
        return false;
    }
    return false;   
}

$scope.increaseLimit = function(limit) {
    $scope.limit = $scope.limit + 2;
}

$scope.increaseReplyLimit = function(limit,index) {
    $scope.limits[index] = parseInt(limit) + 2;
}

});

我根据我有多少'父级'评论来填充这个单独的限制数组,然后我通过引入许多新评论来增加它。现在我只是按顺序显示评论,最新显示的是,所以我不必跟踪哪个'限制'属于哪个评论;我可以简单地在数组的开头添加新的。

至于在我的嵌套ng-repeat中访问$ scope.limits数组并将其用作LimitTo变量,我使用以下变量:limits [$ index]。

请参阅下面的更新标记:

<div ng-controller="CommentsController" >
<!-- Comment Repeater Starts Here -->
<div ng-repeat="comment in comments | limitTo: limit track by comment.id" >
    {{ comment.comment }}

    <!-- Nested Reply Comments Start Here -->
    <div ng-repeat="reply in comment.replies | limitTo: limits[$index] track by reply.id" >
        <div class="comment-text" >
            {{ reply.comment }}
        </div>
    </div>
    <a href="#" ng-click="increaseReplyLimit(limits[$index], $index)" ng-show="hasMoreComments(comment.replies, limits[$index])" >View More Replies</a>
</div>
<a href="#" ng-click="increaseLimit(limit)"    ng-show="hasMoreComments(comments,limit)" >View More Comments</a>
</div>

上面修复了我遇到的问题,我使用的动态变量用于我的嵌套ng-repeat的limitTo被覆盖。我确实需要让$ scope.limits更好地与我的数据同步,但我希望这可以帮助遇到同样问题的其他人。

干杯