AngularJS:在隔离作用域并绑定到parentFunction之后,如何将参数传递给这个parentFunction?

AngularJS:在隔离作用域并绑定到parentFunction之后,如何将参数传递给这个parentFunction?,angularjs,angularjs-directive,angularjs-scope,angularjs-ng-repeat,Angularjs,Angularjs Directive,Angularjs Scope,Angularjs Ng Repeat,我正在努力理解AngularJS中的作用域,并且遇到了一些问题。 我创建了一个简单的“注释”应用程序 有一个用于发布评论的输入框(文本+回复按钮)[工作正常] 单击“回复”按钮可取消隐藏另一个用于发布回复的输入框(带有“PublishReply”按钮) 单击“PublishReply”按钮,在原始评论下方发布回复,并将其缩进 我使用ng repeat在“commentsDirective”中生成评论,并在每个ng repeat中嵌入“replyDirective”。我能够从子指令的隔离作用域绑定

我正在努力理解AngularJS中的作用域,并且遇到了一些问题。 我创建了一个简单的“注释”应用程序

  • 有一个用于发布评论的输入框(文本+回复按钮)[工作正常]
  • 单击“回复”按钮可取消隐藏另一个用于发布回复的输入框(带有“PublishReply”按钮)
  • 单击“PublishReply”按钮,在原始评论下方发布回复,并将其缩进
  • 我使用ng repeat在“commentsDirective”中生成评论,并在每个ng repeat中嵌入“replyDirective”。我能够从子指令的隔离作用域绑定父作用域的函数,但是我不能将参数传递给这个函数

    同样,我认为,一个与范围相关的问题阻止我在点击“回复”按钮时隐藏/取消隐藏“replyDirective”

    谢谢你的帮助

    以下是plunker中的代码:

    
    发表评论
    angular.module('注释',[])
    .controller('mainController',函数($scope){
    $scope.comments=[
    {id:1,parentId:0,内容:'first comment'},
    {id:2,parentId:0,内容:'second comment'}
    ];
    $scope.publishComment=函数(commentId、commentParentId、contentForPublishing){
    如果(commentId==null){commentId=$scope.comments.length+1;}//此(commentId==null)仅从publishComments发送,而不是从publishReply发送
    $scope.comments.push({id:commentId,parentId:commentParentId,content:contentForPublishing});
    $scope.contentForPublishing=“”;
    }
    $scope.replyWidgetVisible=false;
    $scope.showReplyWidget=函数(){
    $scope.replyWidgetVisible=true;
    }
    })
    .directive('commentsDirective',function(){
    返回{
    限制:'E',
    //模板:“”+
    模板:“”+
    'id:{comment.id}}parentId:{{comment.parentId}}
    >{{comment.content}
    '+ “答复”+ // '' + '' + '' }; }) .directive('replyDirective',function(){ 返回{ 限制:'E', 范围:{ 出版答复:"&", commentsArray:“=”, replyWidgetVisible:“=” }, 模板:“发布答复” }; });
    基本上,您需要“获取”publishComment函数,因为使用
    publish reply=“publishComment()”
    可以告诉Angular调用
    publishComment
    ,而不带任何参数,不管您在隔离作用域上传递的参数是什么。因此,要真正到达
    publishComment
    函数(不仅仅是预定义的执行函数),以便传入参数,您需要:

    .directive('commentsDirective',function(){
    返回{
    限制:'E',
    模板:“”+
    'id:{comment.id}}parentId:{{comment.parentId}}
    >{{comment.content}
    '+ “答复”+ '' + '', 链接:功能(范围){ scope.publishReply=函数(){ 返回scope.publishComment; } } }; })
    .directive('replyDirective',function(){
    返回{
    限制:'E',
    范围:{
    出版答复:"&",
    commentsArray:“=”,
    replyWidgetVisible:“=”
    },
    模板:“发布答复”,
    链接:功能(范围){
    scope.publishReply=scope.publishReply();
    }
    };
    });
    
    想象一下你正在做的事情:
    (function(){return scope.publishComment();})(5,1,contentForPublishing)

    当传递的函数是可变的时,执行“get reference to function”父范围绑定非常有用。例如,
    my cool function=“doThis()”
    和应用程序的另一部分
    my cool function=“doThat()”
    。它们的存在使您可以在许多情况下重用相同的指令,但这里的情况并非如此

    一种更简单的方法是从隔离作用域
    $emit
    发布事件,并在comments指令中捕获它。或者使用
    true
    创建一个作用域,以便您可以在新创建的子作用域中直接从父作用域访问函数

    请参见此处更新的plnkr


    以下是plnkr,它显示了如何只打开一个回复框(如果您愿意,可以打开任意多个回复框)(请参阅之前的修订,了解每个注释的小部件状态)

    您正在尝试将
    contentForPublishing
    分配给父范围,但没有为其创建双向绑定。您还使用相同的指令创建了两个元素,但它们的作用域不同。它们应该放在一起(因为每个评论都可以有一个回复)。我不打算将contentForPublishing分配给父作用域,因为我认为contentForPublishing单独存在于父作用域和独立作用域上是可以接受的。在隔离范围中,我只打算将其用作publishReply()的属性。到目前为止,这个publishReply()甚至不接受硬编码的值。不过,谢谢你仔细阅读。这很容易解决,这会让答案变得更清楚。这很有效。谢谢但我不知道“commentsDirective”如何访问scope.publishReply(是因为我在隔离范围定义中将它们绑定为“=”?)。让我来
    <body ng-app="comments">
        <div ng-controller="mainController">
            <div class="publishComment"><input type="text" ng-model="contentForPublishing"/><button ng-click="publishComment(null, 0, contentForPublishing)">Publish Comment</button></div>
            <comments-directive></comments-directive>
        </div>
    </body>
    
    
    <script>
        angular.module('comments', [])
                .controller('mainController', function($scope) {
                    $scope.comments = [
                        { id: 1, parentId: 0, content:'first comment'},
                        { id: 2, parentId: 0, content:'second comment'}
                    ];
                    $scope.publishComment = function (commentId, commentParentId, contentForPublishing){
                        if (commentId === null) {commentId = $scope.comments.length + 1;} // this (commentId === null) is sent only from the publishComments and not from publishReply
                        $scope.comments.push( { id: commentId, parentId:commentParentId, content:contentForPublishing } );
                        $scope.contentForPublishing = "";
                    }
                    $scope.replyWidgetVisible = false;
                    $scope.showReplyWidget = function() {
                        $scope.replyWidgetVisible = true;
                    }
                })
                .directive('commentsDirective', function() {
                    return {
                        restrict: 'E',
    //                    template:   '<div id="{{comment.id}}" class="commentWrapper" ng-class="{{ {true: '', false: 'indentLeft'}[{{comment.parentId}} === 0] }}" ng-repeat="comment in comments">' +
                        template:   '<div id="{{comment.id}}" class="commentWrapper" ng-repeat="comment in comments">' +
                                        'id: {{comment.id}} parentId: {{comment.parentId}}<br>>> {{comment.content}}<br>' +
                                        '<button class="reply" ng-click="showReplyWidget()">Reply</button>' +
    //                                    '<reply-directive publish-reply="publishComment()" ng-show="{{replyWidgetVisible}}" reply-widget-visible="replyWidgetVisible"></reply-directive>' +
                                        '<reply-directive publish-reply="publishComment()" comments-array="comments"></reply-directive>' +
                                    '</div>'
                    };
                })
                .directive('replyDirective', function() {
                    return {
                        restrict: 'E',
                        scope: {
                            publishReply: '&',
                            commentsArray: '=',
                            replyWidgetVisible: '='
                        },
                        template: '<div class="publishComment"><input type="text" ng-model="contentForPublishing"/><button ng-click="publishReply(5, 1, contentForPublishing)">Publish Reply</button></div>'
                    };
                });
    </script>