AngularJS在父和子范围指令之间共享数据

时间:2014-11-20 10:22:30

标签: javascript angularjs angularjs-directive

我有一个名为waComments的小部件指令,它通过RESTful服务加载组件并显示它们。在我看来,我正在使用ng-repeat循环遍历它们并使用按钮渲染它们,如果按下则显示对表单的新回复。这是由waCommentsReply指令处理的。一个waComments小部件有许多类型为waCommentsReply的子指令。填写并提交表单后,我想在评论列表的顶部添加新评论。因此,两个指令都必须共享评论数据。

我已尝试在此Sharing data between directives实现此功能,但没有太大成功,我添加新评论时评论数据不会更新。我看到RESTful API调用工作并返回数据,所以这不是问题。

为什么我Sharing data between directives的实施不适用于我的情况?

waCommentsReply指令:

waFrontend.directive('waCommentsReply', ['$rootScope', 'Comment', 'WaFormValidation', 'WaCommentStore', function($rootScope, Comment, WaFormValidation, WaCommentStore) {
    return {
        restrict: 'E',
        templateUrl: '/stubs/comment-form.html',
        transclude: true,
        scope: {
            replyTo: '@replyTo',
            replyFormList: '=replyFormList',
            loggedIn: '@loggedIn',
            model: '@model',
            id: '@id',
            cancelButton: '@cancelButton'
        },
        controller: function($scope) {
            $scope.comments = WaCommentStore;
            if ($scope.cancelButton == undefined) {
                $scope.cancelButton = true;
            } else {
                $scope.cancelButton = false;
            }

            $scope.comment = $scope.commentForm = {
                Comment: {
                    author_name: '',
                    body: '',
                    model: $scope.model,
                    foreign_key: $scope.id,
                    parent_id: $scope.replyTo
                }
            };

            $scope.$watch('replyFormList', function (newValue, oldValue) {
                if (newValue) {
                    $scope.replyFormList = newValue;
                }
            });

            if ($scope.loggedIn == undefined) {
                $scope.loggedIn = false;
            }

            /**
             * Handles the submission and response of a reply
             *
             * @return void
             */
            $scope.reply = function() {
                Comment.add($scope.comment).then(function(result) {
                    if (result.status == 'fail' || result.validation != undefined) {
                        $scope.validationErrors = result.validation;
                        WaFormValidation.validate(result.validation, $scope.commentForm);
                    } else if (result.status == 'success') {
                        //$scope.$parent.comments.unshift(result.data.comment);
                        //$scope.comments.unshift(result.data.comment);
                        $scope.comments.comments.unshift(result.data.comment);
                        //WaCommentStore.append($scope.model, $scope.id, result.data.comment);
                        $scope.comments, $scope.id, result.data.comment
                        $scope.comment = {};
                        $scope.replyFormList[$scope.replyTo] = false;
                    }
                });
            };

            $scope.close = function() {
                $scope.comment = {};
                if ($scope.replyFormList[$scope.replyTo] != undefined) {
                    $scope.replyFormList[$scope.replyTo] = false;
                }
            }
        }
    };
}]);

WaCommentStore指令:

waFrontend.factory('WaCommentStore', function() {
    return {
        comments: []
    };
});

waComments指令:

waFrontend.directive('waComments', ['$rootScope', 'Comment', 'WaCommentStore', function($rootScope, Comment, WaCommentStore) {
    return {
        restrict: 'E',
        templateUrl: '/stubs/comments.html',
        scope: {
            model: '@commentModel',
            id: '@commentFk'
        },
        controller: function($scope) {
            $scope.comments = WaCommentStore;
            $scope.loaded = false;
            $scope.loadedMore = true;
            $scope.currentPage = 1;
            $scope.loggedIn = false;
            $scope.paging = {};
            $scope.replyFormList = {};

            Comment.comments($scope.model, $scope.id).then(function(result) {
                $scope.comments.comments.push.apply($scope.comments.comments, result.data.comments);
                $scope.loggedIn = result.data.loggedIn;
                $scope.paging = result.paging.Comment;
                $scope.loaded = true;
            });

            $scope.loadMore = function() {
                $scope.loadedMore = false;
                if ($scope.paging.nextPage == false) {
                    //return false;
                }
                var options = {
                    page: $scope.paging.page + 1
                };
                Comment.comments($scope.model, $scope.id, options).then(function(result) {

                    $scope.comments.comments.push.apply($scope.comments.comments, result.data.comments);
                                        $scope.paging = result.paging.Comment;
                    $scope.loadedMore = true;
                });
            };

            $scope.submitComment = function() {
                //alert($scope.author_name + $scope.body);
            };

            $scope.reply = function(replyId) {
                $scope.replyFormList[replyId] = true;
            }
        }
    };
}]);

2 个答案:

答案 0 :(得分:0)

因为在两个指令中都定义了范围:{}基本上它意味着您定义了这些指令以使用隔离范围。 对于隔离范围,范围/指令无法查看父范围内的内容。 但是,父范围可以受到子范围更改的影响,具有双向绑定定义。

https://docs.angularjs.org/guide/scope

答案 1 :(得分:0)

尝试像这样更改共享数据

waFrontend.factory('WaCommentStore', function() {
   var comments = [];

   var getComments = function() { return comments; }

   var setComments = function(data) { comments = data; }

   return {
        getComments : getComments ,
        setComments : setComments 
    };
});

我想把它作为评论,但对你来说很难理解。

如果有效,请告诉我,否则我会删除此答案。