AngularJS : after isolating scope and binding to a parentFunction, 如何将参数传递给这个parentFunction?

标签 angularjs angularjs-directive angularjs-scope angularjs-ng-repeat

我正在努力理解 AngularJS 中的作用域,但遇到了问题。 我创建了一个简单的“评论”应用程序

  1. 有一个用于发布评论的输入框(文本+“回复”按钮)[这工作正常]
  2. 点击“回复”按钮会取消隐藏另一个用于发布回复的输入框(带有“PublishReply”按钮)
  3. 点击“PublishReply”按钮,在原始评论下方发布回复并缩进。

我使用 ng-repeat 在“commentsDirective”中生成注释,并在每个 ng-repeat 中嵌入“replyDirective”。我能够从子指令的隔离范围绑定(bind)父范围的函数,但我无法将参数传递给该函数。

我再次认为,与范围相关的问题阻止我通过单击“回复”按钮来隐藏/取消隐藏“replyDirective”。

感谢您的帮助。

这是plunker中的代码:http://plnkr.co/edit/5AmlbOh6iEPby9K2LJDE?p=preview

<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>

最佳答案

基本上,您需要“获取”publishComment 函数,因为使用 publish-reply="publishComment()" 您告诉 Angular 在不带任何参数的情况下调用 publishComment,无论您在隔离范围内传递什么参数。因此,要真正到达 publishComment 函数(而不仅仅是预定义的执行函数),以便您可以传入参数,您需要:

.directive('commentsDirective', function() {
    return {
       restrict: 'E',
       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="publishReply()" comments-array="comments"></reply-directive>' +
       '</div>',
       link: function(scope){
         scope.publishReply = function(){
           return scope.publishComment;
         }
       }
    };
})
.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>',
       link: function(scope) {
         scope.publishReply = scope.publishReply();
       }
    };
});

想象一下,如果您正在执行以下操作:(function(){ return range.publishComment(); })(5, 1, contentForPublishing);

当传递的函数是可变的时,执行“获取对函数的引用”父作用域绑定(bind)主要有用。例如,my-cool-function="doThis()" 以及应用的另一部分 my-cool-function="doThat()"。它们的存在是为了让您可以在许多情况下重用相同的指令,但这里的情况并非如此。

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

在此处查看更新的 plnkr http://plnkr.co/edit/nOWwFJ35XRXaIoxNPlW4?p=preview

这里是 plnkr,展示了如何仅打开一个回复框(如果您愿意,可以保持多个回复框打开)http://plnkr.co/edit/za16eHPzltGLjK5ra1Vb?p=preview (请参阅之前的修订版以了解每个评论的小部件状态)

关于AngularJS : after isolating scope and binding to a parentFunction, 如何将参数传递给这个parentFunction?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22567081/

相关文章:

javascript - 在 ngForm 中触发 'enter' 按键上的某个按钮

javascript - 推迟尺寸计算直到 ui 呈现

javascript - Angular 自定义指令模板行为

javascript - 从另一个指令获取指令的属性?

javascript - Angular JS双向绑定(bind)变量不更新父范围

angularjs - 在 Angular 1.4 指令上使用 "@"作为文本属性时,如何替换隔离范围的值? (适用于 Angular 1.3)

javascript - 隔离范围 '=' 未分配

javascript - 等待根据指令发起的 promise 解决的最佳方式是什么?

javascript - 当我单击元素的子元素时更改状态(+AngularJS)

javascript - 指令无法替换模板中的变量 : Syntax Error