javascript - transclude() 和 ng-repeat 玩得不好

标签 javascript html angularjs

尝试使用 transclude() 从指令中嵌入包含 ng-repeat 语句的 HTML 部分会非常严重。它不是每次重复所有元素一次,而是将所有元素重复一次,然后再重复一次,然后再重复一次,重复的次数不定,通常约为 17 次。

我烦人地必须使用这种相当 hack-y 的方式来嵌入内容,因为我无法使用普通的模板指令,也无法使用 angular-ui-bootstrap $modal 函数,这需要添加模板直接到它。

我已经将问题范围缩小到将内容注入(inject)页面之前,在 getBody() 函数中放置一个断点并输入 transclude() 进入控制台显示额外的重复已经发生。

我知道问题不在于 ng-repeat,因为我可以复制主 HTML 中指令调用中的内容并将其直接放在它后面,并且重复可以正常工作。

任何有关问题所在或如何修复问题的建议都将受到赞赏。

下面是我用来演示的代码的精简版本:

HTML 主页面:

<div data-wp-modal="{{'registration.registeredAddresses.allAddressesHead' | translate}} {{entity.type}}"
         data-show="controller.viewModel.openOrganisationAddressModal">
        <table class="table" data-table-name="registeredAddresses">
            <tbody>
                <tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']">
                    <td>{{animal}}</td>
                </tr>
            </tbody>
        </table>
    </div>

指令:

// @ngInject
exports.wpModal = function(lpCoreBus, lpCoreUtils, lpWidget, $compile, $modal, $modalStack) {

    return {
        restrict: 'EA',
        replace: true,
        scope: {
            show: "=",
        },
        transclude: true,
        link: function (scope, element, attr, ctrl, transclude) {

            scope.$watch("show", function(newValue, oldValue) {
                if (newValue && newValue !== oldValue) {
                    var modalInstance = $modal.open({
                        "animation": true,
                         "scope": scope,
                         "controller": "ModalController",
                         "templateUrl": lpCoreUtils.resolvePortalPlaceholders("$(contextPath)/static/launchpad/modules/module-wp-modal/templates/modal.html"),
                         "size": "md"

                    });

                    modalInstance.result.then(function () {
                        // User confirmed the action [performed after doConfirm()]
                        scope.buttonConfirmAction();

                    }, function () {
                        // User cancelled the action [performed after doCancel()]
                        scope.buttonCancelAction();
                    });

                    scope.show = false;
                }

            });

            scope.getBody = function() {

                for (var i = 0; i < transclude().length; i++) {
                    console.log(transclude()[i]);
                    document.querySelector(".modal-body").appendChild(transclude()[i]);
                }
            }


        }
    };
};

模态模板:

<div data-ng-init="getBody()">

    <div class="modal-body">
    </div>


</div>

输出:

<div class="modal-body">
    <table class="table ng-scope" data-table-name="registeredAddresses">
        <tbody>
            <!-- ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">cat</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">dog</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">bird</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">turtle</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">cat</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">dog</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">bird</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">turtle</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">cat</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">dog</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">bird</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">turtle</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">cat</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">dog</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">bird</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">turtle</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">cat</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">dog</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">bird</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">turtle</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">cat</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">dog</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">bird</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">turtle</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">cat</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">dog</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">bird</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">turtle</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">cat</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">dog</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">bird</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">turtle</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">cat</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">dog</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">bird</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">turtle</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">cat</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">dog</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">bird</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] --><tr data-ng-repeat="animal in ['cat', 'dog', 'bird', 'turtle']" class="ng-scope">
                <td class="ng-binding">turtle</td>
            </tr><!-- end ngRepeat: animal in ['cat', 'dog', 'bird', 'turtle'] -->
        </tbody>
    </table>
</div>

骗子:http://plnkr.co/edit/8DD1rgTYOLYHAtsLdm9s?p=preview

最佳答案

我认为问题在于您多次调用 transclude() ,从而多次链接相同的 DOM 元素。要查看这一点,您可以在 ngRepeatLink 函数内设置断点

return function ngRepeatLink($scope, $element, $attr, ctrl, $transclude) {

在 angular.js 源中。为了避免这种情况,您可以使用以下代码:

app.directive('test', function() {
    return {
        transclude: true,
        scope: {
          show: '='
        },
        link: function(scope, element, attr, ctrl, transclude) {
            var linked = transclude();
            for (var i = 0; i < linked.length; i++) {
              element.append(linked[i]);
            }
        }
    };
});

或者这样更好:

app.directive('test', function() {
    return {
        transclude: true,
        scope: {
          show: '='
        },
        link: function(scope, element, attr, ctrl, transclude) {
            var linked = transclude();
            element.append(linked);
        }
    };
});

通常,您不应该将指令创建的 DOM 追加到指令元素之外,因此我将其追加到指令元素中。

关于javascript - transclude() 和 ng-repeat 玩得不好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40146850/

相关文章:

javascript - 如果所有三个单选按钮均为 false,则不验证

css - 在调整大小 css 上更改 div 位置

javascript - 使用 Angular 的基本 HATEOAS - 加载入口点

internet-explorer - 如何让 AngularJS 路由在 IE 8 上工作

asp.net - 在重用和逻辑封装方面使用 ASP.NET 构建 JavaScript UI 代码的最佳方式?

javascript - JavaScript 循环中的异步调用 - Apache Cordova

javascript - iOS:WKWebView 中的 Javascript 代码在从照片库中选择照片并上传到服务器之前出现 “query cancelled” 错误

html - CSS Puzzle - Classed Link Span 在悬停时不会改变颜色

javascript - 使用不同的 ng-controller 和 ng-include

javascript - 网页上的谷歌广告可以从当前页面抓取内容吗?