使用angularJS和jQuery / angular bootstrap进行内存泄漏

时间:2014-04-29 09:52:38

标签: javascript jquery angularjs angular-ui-bootstrap

我有一个每分钟更新的ng-repeat列表。它的卡片列表包含标题,描述,日期等内容。 在这些卡片中还有一个angular-ui-bootstrap popover,我用它来显示这些卡片上的评论。

当列表更新时,popover将保留一些引用,这将创建许多分离的dom元素。

下面是一些代码。

我使用的指令。

    .directive('mypopover', function ($compile, $templateCache) {

    var getTemplate = function (contentType) {
        var template = '';
        switch (contentType) {
            case 'user':
                template = $templateCache.get("templateId.html");
                break;
        }
        return template;
    }
    return {
        restrict: "A",
        link: function ($scope, element, attrs) {
            var popOverContent;

            popOverContent = getTemplate("user");

            popOverContent = $compile("<span>" + popOverContent + "</span>")($scope);

            var options = {
                content: popOverContent,
                placement: "bottom",
                html: true,
                trigger: "manual",
                selector: '.fa-comment',
                date: $scope.date,
                animation: true
            };

            $(element).popover(options).on("mouseenter", function () {
                var _this = this;
                $(this).popover("show");
                $('.popover').linkify();
                $(".popover").on("mouseleave", function () {
                    $(this).popover('destroy');
                    $('.popover').remove();
                });
            }).on("mouseleave", function () {
                var _this = this;
                setTimeout(function () {
                    if (!$(".popover:hover").length) {
                        $(this).popover('destroy');
                        $('.popover').remove();
                    }
                }, 350);
            });

            var destroy = function () {
                $(element).popover('destroy');
            }

            $scope.$on("$destroy", function () {
                destroy();
            });
        }
    }
})

来自html .. bo-something只是我使用的单向绑定,而不是角度

的普通双绑定
 <a bo-href="c.ShortUrl" target="_blank" bindonce ng-repeat="c in cards | filter:searchText | limitTo: limitValue[$index] track by c.Id">
                    <div class="panel detachable-card">
                        <div class="panel-body" bo-class="{redLabel: c.RedLabel, orangeLabel: c.OrangeLabel}">
                            <!-- Comments if any -->
                            <script type="text/ng-template" id="templateId.html">
                                <div ng-repeat="comment in c.Comment track by $index">
                                    <strong style="margin-bottom: 20px; color:#bbbbbb; white-space: pre-wrap;">{{c.CommentMember[$index]}}</strong>
                                    <br />
                                    <span style="white-space: pre-wrap;">{{comment}}</span>
                                    <hr />
                                </div>
                            </script>
                            <span bo-if="c.Comment" data-container="body" mypopover style="float:right"><i class="fa fa-comment fa-lg"></i></span>

                            <!-- Card info -->
                            <strong style="font-size:12px; color:#999999"><span bo-if="!c.BoardNameOverride" bo-text="c.NameBoard"></span> <span bo-if="c.BoardNameOverride" bo-text="c.BoardNameOverride"></span></strong>
                            <br />
                            <strong bo-text="c.Name"></strong>
                            <br />
                            <span bo-if="c.Desc" bo-text="c.Desc"><br /></span>

                        </div>
                    </div>
                </a>

在一次更新后继承了网站的堆快照。 http://i.stack.imgur.com/V4U1O.png

所以我对javascript一般都很糟糕,我对这个指令有疑问。我原以为.popover('destroy')会删除引用,但它似乎没有..

非常感谢任何帮助..

1 个答案:

答案 0 :(得分:0)

你为什么一遍又一遍地摧毁弹出窗口?每次移动鼠标时都不需要破坏弹出窗口。只需显示并隐藏弹出窗口即可。它在内存上比不断破坏和重新创建弹出窗口要好得多。

但是,您可能没有意识到,引导组件与AngularJS不能很好地协作。 Bootstrap组件的构建方式不允许其中的内容容易更新,这会在您使用AngularJS时出现问题,因为更新模型已内置到框架中。这就是为什么AngularUI项目在AngularJS中从头开始重写他们的Javascript组件,这样他们的行为就像你期望的那样。我想你会发现那些更容易使用的东西。

http://angular-ui.github.io/bootstrap/

如果您使用的是bootstrap 2.3 AngularUI v0.8是支持bootstrap v2.3的最后一个版本。