简体   繁体   中英

How to fix the ng-click doesn't work in recursive directive template

I am using ng-click in template of recursive directive. but not work.

Here is the code https://jsfiddle.net/qxz7506n/

When i click the 'root load more button', it work, but the 'child load more button' not work, and how to pass the child object inside the ngclick through directive to controller scope and console it.

Html

<div ng-app='demoA'>
    <div ng-controller="IndexCtrl">
        <collection collection='tasks' reply-msg="replyMsg(data)" load-more="loadMore()">
        </collection>
    </div>
</div>

Collection Directive

.directive('collection', function () {
    return {
        restrict: "E",
        replace: true,
        scope: {
            collection: '=',
            member: '=',
            replyMsg: '&',
            loadMore: '&'
        },
        template: "<ul><member ng-repeat='member in collection track by $index' floor='$index + 1' member='member' reply-msg='replyMsg({data: member.name})'></member><li><input type='button' value='load more...' ng-click='loadMore()' /></li></ul>"
    }
})

Member Directive

.directive('member', function ($compile) {
    return {
        restrict: "E",
        replace: true,
        scope: {
           floor: '=',
           member: '=',
           replyMsg: '&',
           loadMore: '&'
        },
        template: "<li>" + 
                "<div ng-if='member.isReply'>#{{floor}}</div>" + 
                "<div>{{member.name}}</div>" + 
                "<div ng-if='!member.isReply'><input type='button' value='Reply' ng-click='replyMsg({data: member.name})'/></div>" + 
  "</li>",
        link: function (scope, element, attrs) {
            if (angular.isArray(scope.member.children)) {
                element.append("<collection collection='member.children' reply-msg='replyMsg({data: member.name})' load-more='loadMore()'></collection>"); 
                $compile(element.contents())(scope)
            }
        }
    }
})

For example,

when i click the 'root load more button', it through the directive to controller scope and console as a object include the "Europe" and "South America".

when i click the 'child load more button', it through the directive to controller scope and console as a object include the "italy" and "Spain".

I think i fixed it, see this updated JSFiddle.

The problem was that you did not pass the loadMore and replyMsg functions as references to the sub-directives. Instead you invoked them like so: load-more="loadMore()" . This should only be done in ng-click . I also changed your '&' to '=' in the directives for the passed methods.

HTML

<div ng-app='demoA'>
    <div ng-controller="IndexCtrl">
    <collection collection='tasks' reply-msg="replyMsg" load-more="loadMore">
    </collection>
    </div>
</div>

JavaScript

angular.module('demoA', [])
    .directive('collection', function () {
        return {
            restrict: "E",
            replace: true,
            scope: {
                collection: '=',
                member: '=',
                replyMsg: '=',
                loadMore: '='
            },
            template: "<ul>" + 
                "<member ng-repeat='member in collection track by $index' floor='$index + 1' member='member' reply-msg='replyMsg' load-more='loadMore'></member>" + 
                "<li><input type='button' value='load more...' ng-click='loadMore()' /></li>" + 
            "</ul>"
        }
    })
    .directive('member', function ($compile) {
        return {
            restrict: "E",
            replace: true,
            scope: {
                floor: '=',
                member: '=',
                replyMsg: '=',
                loadMore: '='
            },
            template: "<li>" + 
            "<div ng-if='member.isReply'>#{{floor}}</div>" + 
            "<div>{{member.name}}</div>" + 
            "<div ng-if='!member.isReply'><input type='button' value='Reply' ng-click='replyMsg({data: member.name})'/></div>" + 
            "</li>",
            link: function (scope, element, attrs) {
                if (angular.isArray(scope.member.children)) {
                    element.append("<collection collection='member.children' reply-msg='replyMsg' load-more='loadMore'></collection>"); 
                    $compile(element.contents())(scope)
                }
            }
        }
    })

    .controller('IndexCtrl', function ($scope) {
        $scope.replyMsg = function(data) {
            alert(data);
        };
        $scope.loadMore = function() {
            alert("clicked");
        };
        $scope.tasks = [
            {
                name: 'Europe',
                children: [
                    {
                        name: 'Italy',
                        isReply: true,
                    }, 
                    {
                        name: 'Spain',
                        isReply: true,
                    }
                ]
            }, 
            {
                name: 'South America',
                children: []
            }
        ];
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM