将对象推送到数组时,ng-repeat不会更新

时间:2015-12-15 08:53:48

标签: javascript arrays angularjs angularjs-scope angularjs-ng-repeat

我一直在Coursera上学习Angular JS的课程,在使用表单在数组上推送内容后,ng-repeat无法更新我的视图。当我在提交表单后尝试记录数组的内容时,似乎一切都正确(元素被推送到数组上,但我的视图没有刷新以反映这种变化。

我一直试图解决这个问题两天了,但是因为我仍然无法解决这个问题而且我被困住了,我将在这里发布我的部分代码,我希望有人可以帮我修复它了解发生了什么。

    <div class="col-xs-9 col-xs-offset-1" ng-controller="DishDetailController">
              <h4>Customer Comments&nbsp;&nbsp;&nbsp;&nbsp;<small>Sort by: </small>
                <input class="input-sm" type="text" ng-model="in"></h4>
              <blockquote ng-repeat="comment in dish.comments
                | orderBy:in">
                <p>
                    {{comment.rating}} Stars
                </p>
                <p>
                   {{comment.comment}}
                </p>
                <footer>{{comment.author}}, {{comment.date | date: 'MMM. dd, yyyy'}}</footer>
              </blockquote>
            </div>
<div class="col-xs-9 col-xs-offset-1" ng-controller="DishCommentController">
              <ul class="list-unstyled" ng-show="!commentForm.name.$error.required && !commentForm.name.$pristine
                && !commentForm.comment.$error.required && !commentForm.comment.$pristine">
                <blockquote>
                  <p>
                    {{comment.rating}} Stars
                  </p>
                  <p>
                    {{comment.comment}}
                  </p>
                  <footer>{{comment.author}},</footer>
                </blockquote>
              </ul>
                <form class="form-horizontal" name="commentForm"
                        ng-submit="submitComment()" novalidate>
                    <div class="form-group" ng-class="{'has-error': commentForm.name.$error.required && !commentForm.name.$pristine}">
                      <label for="name" class="col-sm-2 control-label">Name</label>
                      <div class="col-sm-10">
                        <input type="text" ng-model="comment.author" name="name" class="form-control" id="name" placeholder="Enter Your Name" required>
                      </div>
                    </div>
                    <div class="form-group">
                      <label class="col-sm-2 control-label">Number of Stars</label>
                      <div class="col-sm-10">
                        <label class="radio-inline"><input type="radio" name="rating" ng-value=1 checked="{{chRating(1)}}" ng-model="comment.rating">1</label>
                        <label class="radio-inline"><input type="radio" name="rating" ng-value=2 checked="{{chRating(2)}}" ng-model="comment.rating">2</label>
                        <label class="radio-inline"><input type="radio" name="rating" ng-value=3 checked="{{chRating(3)}}" ng-model="comment.rating">3</label>
                        <label class="radio-inline"><input type="radio" name="rating" ng-value=4 checked="{{chRating(4)}}" ng-model="comment.rating">4</label>
                        <label class="radio-inline"><input type="radio" name="rating" ng-value=5 checked="{{chRating(5)}}" ng-model="comment.rating">5</label>
                      </div>
                    </div>
                    <div class="form-group" ng-class="{'has-error': commentForm.comment.$error.required && !commentForm.comment.$pristine}">
                      <label class="col-sm-2 control-label">Your Comments</label>
                      <div class="col-sm-10">
                        <textarea class="form-control" id="comment" ng-model="comment.comment" name="comment" rows="12" required></textarea>
                        <span ng-show="commentForm.comment.$error.required && !commentForm.comment.$pristine" class="help-block">Your comments are required.</span>
                      </div>
                    </div>
                    <div class="form-group">
                      <div class="col-sm-10 col-sm-offset-2">
                        <button type="submit" name="button" class="btn btn-primary"
                          ng-disabled="commentForm.$invalid">Submit Comment</button>
                      </div>
                    </div>
                </form>
            </div>

以下是我的javascript代码中处理此表单的部分:

.controller('DishDetailController', ['$scope', function($scope) {

        var dish={
                      name:'Uthapizza',
                      image: 'images/uthapizza.png',
                      category: 'mains',
                      label:'Hot',
                      price:'4.99',
                      description:'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.',
                       comments: [
                           {
                               rating:5,
                               comment:"Imagine all the eatables, living in conFusion!",
                               author:"John Lemon",
                               date:"2012-10-16T17:57:28.556094Z"
                           },
                           {
                               rating:4,
                               comment:"Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
                               author:"Paul McVites",
                               date:"2014-09-05T17:57:28.556094Z"
                           },
                           {
                               rating:3,
                               comment:"Eat it, just eat it!",
                               author:"Michael Jaikishan",
                               date:"2015-02-13T17:57:28.556094Z"
                           },
                           {
                               rating:4,
                               comment:"Ultimate, Reaching for the stars!",
                               author:"Ringo Starry",
                               date:"2013-12-02T17:57:28.556094Z"
                           },
                           {
                               rating:2,
                               comment:"It's your birthday, we're gonna party!",
                               author:"25 Cent",
                               date:"2011-12-02T17:57:28.556094Z"
                           }

                       ]
                };

        $scope.dish = dish;

    }])

    .controller('DishCommentController', ['$scope', function($scope) {

        //Step 1: Create a JavaScript object to hold the comment from the form
        $scope.comment = {rating: 5, comment:"", author:"", date:""};
        $scope.submitComment = function () {

            //Step 2: This is how you record the date
            $scope.comment.date = new Date().toISOString();

            // Step 3: Push your comment into the dish's comment array
            $scope.dish.comments.push($scope.comment);

            //Step 4: reset your form to pristine
            $scope.commentForm.$setPristine();
            //Step 5: reset your JavaScript object that holds your comment
            $scope.comment = {rate: 5, comment:"", author:"", date:""};
        }
    }]);

我希望有人可以帮助我。提前谢谢。

2 个答案:

答案 0 :(得分:2)

只需将您的父控制器DishDetailController添加到父div,即ng-controller="DishDetailController",以便DishCommentController可以继承DishDetailController控制器的范围。

在此之后,当您将内容推送到$scope.dish.comments时,它会更新父$scope的内容,从而更新到视图。

运行以下示例,例如:

angular.module('sa', [])
  .controller('DishDetailController', ['$scope',
    function($scope) {

      var dish = {
        name: 'Uthapizza',
        image: 'images/uthapizza.png',
        category: 'mains',
        label: 'Hot',
        price: '4.99',
        description: 'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.',
        comments: [{
            rating: 5,
            comment: "Imagine all the eatables, living in conFusion!",
            author: "John Lemon",
            date: "2012-10-16T17:57:28.556094Z"
          }, {
            rating: 4,
            comment: "Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
            author: "Paul McVites",
            date: "2014-09-05T17:57:28.556094Z"
          }, {
            rating: 3,
            comment: "Eat it, just eat it!",
            author: "Michael Jaikishan",
            date: "2015-02-13T17:57:28.556094Z"
          }, {
            rating: 4,
            comment: "Ultimate, Reaching for the stars!",
            author: "Ringo Starry",
            date: "2013-12-02T17:57:28.556094Z"
          }, {
            rating: 2,
            comment: "It's your birthday, we're gonna party!",
            author: "25 Cent",
            date: "2011-12-02T17:57:28.556094Z"
          }

        ]
      };

      $scope.dish = dish;

    }
  ])

.controller('DishCommentController', ['$scope',
  function($scope) {

    //Step 1: Create a JavaScript object to hold the comment from the form
    $scope.comment = {
      rating: 5,
      comment: "",
      author: "",
      date: ""
    };
    $scope.submitComment = function() {

      //Step 2: This is how you record the date
      $scope.comment.date = new Date().toISOString();

      // Step 3: Push your comment into the dish's comment array
      $scope.dish.comments.push($scope.comment);

      //Step 4: reset your form to pristine
      $scope.commentForm.$setPristine();
      //Step 5: reset your JavaScript object that holds your comment
      $scope.comment = {
        rate: 5,
        comment: "",
        author: "",
        date: ""
      };
    }
  }
]);
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<!-- Moved the DishDetailController to a parent element -->
<div ng-controller="DishDetailController" ng-app="sa">
    <div class="col-xs-9 col-xs-offset-1">
        <h4>Customer Comments&nbsp;&nbsp;&nbsp;&nbsp;
            <small>Sort by:</small>
            <input class="input-sm" type="text" ng-model="in">
        </h4>

        <blockquote ng-repeat="comment in dish.comments | orderBy:in">
            <p>
                {{comment.rating}} Stars
            </p>

            <p>
                {{comment.comment}}
            </p>
            <footer>{{comment.author}}, {{comment.date | date: 'MMM. dd, yyyy'}}</footer>
        </blockquote>
    </div>

    <!-- Now $scope of DishCommentController will inheirt from parent -->
    <div class="col-xs-9 col-xs-offset-1" ng-controller="DishCommentController">
        <form class="form-horizontal" name="commentForm" ng-submit="submitComment()" novalidate>
            <div class="form-group"
                 ng-class="{'has-error': commentForm.name.$error.required && !commentForm.name.$pristine}">
                <label for="name" class="col-sm-2 control-label">Name</label>

                <div class="col-sm-10">
                    <input type="text" ng-model="comment.author" name="name" class="form-control" id="name"
                           placeholder="Enter Your Name" required>
                </div>
            </div>
            <div class="form-group">
                <label class="col-sm-2 control-label">Number of Stars</label>

                <div class="col-sm-10">
                    <label class="radio-inline">
                        <input type="radio" name="rating" ng-value=1              ng-model="comment.rating">1</label>
                    <label class="radio-inline">
                        <input type="radio" name="rating" ng-value=2 ng-model="comment.rating">2</label>
                    <label class="radio-inline">
                        <input type="radio" name="rating" ng-value=3 
                               ng-model="comment.rating">3</label>
                    <label class="radio-inline">
                        <input type="radio" name="rating" ng-value=4 
                               ng-model="comment.rating">4</label>
                    <label class="radio-inline">
                        <input type="radio" name="rating" ng-value=5 
                               ng-model="comment.rating">5</label>
                </div>
            </div>
            <div class="form-group"
                 ng-class="{'has-error': commentForm.comment.$error.required && !commentForm.comment.$pristine}">
                <label class="col-sm-2 control-label">Your Comments</label>

                <div class="col-sm-10">
                <textarea class="form-control" id="comment" ng-model="comment.comment" name="comment" rows="12"
                          required></textarea>
                <span ng-show="commentForm.comment.$error.required && !commentForm.comment.$pristine"
                      class="help-block">Your comments are required.</span>
                </div>
            </div>
            <div class="form-group">
                <div class="col-sm-10 col-sm-offset-2">
                    <button type="submit" name="button" class="btn btn-primary" ng-disabled="commentForm.$invalid">
                        Submit
                        Comment
                    </button>
                </div>
            </div>
        </form>
    </div>
</div>

答案 1 :(得分:0)

DishCommentController中的 $ scope.dish在DishCommentController中不可用。

一个解决方案是:

将dish变量移动到服务中并在服务中使用方法来获取dish变量并向dish变量添加注释。使用DishDetailController和DishCommentController中的服务。

洗碗服务

.service('dishService', function(){

var dish={
            name:'Uthapizza',
                  image: 'images/uthapizza.png',
                  category: 'mains',
                  label:'Hot',
                  price:'4.99',
                  description:'A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.',
                   comments: [
                       {
                           rating:5,
                           comment:"Imagine all the eatables, living in conFusion!",
                           author:"John Lemon",
                           date:"2012-10-16T17:57:28.556094Z"
                       },
                       {
                           rating:4,
                           comment:"Sends anyone to heaven, I wish I could get my mother-in-law to eat it!",
                           author:"Paul McVites",
                           date:"2014-09-05T17:57:28.556094Z"
                       },
                       {
                           rating:3,
                           comment:"Eat it, just eat it!",
                           author:"Michael Jaikishan",
                           date:"2015-02-13T17:57:28.556094Z"
                       },
                       {
                           rating:4,
                           comment:"Ultimate, Reaching for the stars!",
                           author:"Ringo Starry",
                           date:"2013-12-02T17:57:28.556094Z"
                       },
                       {
                           rating:2,
                           comment:"It's your birthday, we're gonna party!",
                           author:"25 Cent",
                           date:"2011-12-02T17:57:28.556094Z"
                       }

                   ]
            };

            this.addComment = function (comment) {
                dish.comments.push(comment);
            }

            this.getDish = function (dish) {
                return dish;
            }                                                             });

控制器

.controller('DishDetailController', ['$scope', 'dishService', function($scope, dishService) {
    $scope.dish = dishService.getDish(); 
})

.controller('DishCommentController', ['$scope', 'dishService', function($scope, dishService) {

    //Step 1: Create a JavaScript object to hold the comment from the form
    $scope.comment = {rating: 5, comment:"", author:"", date:""};
    $scope.submitComment = function () {

        //Step 2: This is how you record the date
        $scope.comment.date = new Date().toISOString();

        // Step 3: Push your comment into the dish's comment array
        dishService.addComment($scope.comment)

        //Step 4: reset your form to pristine
        $scope.commentForm.$setPristine();
        //Step 5: reset your JavaScript object that holds your comment
        $scope.comment = {rate: 5, comment:"", author:"", date:""};
    }
}]);

另一种解决方案是:

制作DishDetail控制器,DishCommentController的父控制器。

<div class="col-xs-9 col-xs-offset-1" ng-controller="DishDetailController"><!--Parent div-->
<h4>Customer Comments&nbsp;&nbsp;&nbsp;&nbsp;
    <small>Sort by:</small>
    <input class="input-sm" type="text" ng-model="in"></h4>
<blockquote ng-repeat="comment in dish.comments
            | orderBy:in">
    <p>
        {{comment.rating}} Stars
    </p>

    <p>
        {{comment.comment}}
    </p>
    <footer>{{comment.author}}, {{comment.date | date: 'MMM. dd, yyyy'}}</footer>
</blockquote>
<!--Child div-->
<div class="col-xs-9 col-xs-offset-1" ng-controller="DishCommentController">
    <ul class="list-unstyled" ng-show="!commentForm.name.$error.required && !commentForm.name.$pristine
            && !commentForm.comment.$error.required && !commentForm.comment.$pristine">
        <blockquote>
            <p>
                {{comment.rating}} Stars
            </p>

            <p>
                {{comment.comment}}
            </p>
            <footer>{{comment.author}},</footer>
        </blockquote>
    </ul>
    <form class="form-horizontal" name="commentForm"
          ng-submit="submitComment()" novalidate>
        <div class="form-group"
             ng-class="{'has-error': commentForm.name.$error.required && !commentForm.name.$pristine}">
            <label for="name" class="col-sm-2 control-label">Name</label>

            <div class="col-sm-10">
                <input type="text" ng-model="comment.author" name="name" class="form-control" id="name"
                       placeholder="Enter Your Name" required>
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-2 control-label">Number of Stars</label>

            <div class="col-sm-10">
                <label class="radio-inline"><input type="radio" name="rating" ng-value=1 checked="{{chRating(1)}}"
                                                   ng-model="comment.rating">1</label>
                <label class="radio-inline"><input type="radio" name="rating" ng-value=2 checked="{{chRating(2)}}"
                                                   ng-model="comment.rating">2</label>
                <label class="radio-inline"><input type="radio" name="rating" ng-value=3 checked="{{chRating(3)}}"
                                                   ng-model="comment.rating">3</label>
                <label class="radio-inline"><input type="radio" name="rating" ng-value=4 checked="{{chRating(4)}}"
                                                   ng-model="comment.rating">4</label>
                <label class="radio-inline"><input type="radio" name="rating" ng-value=5 checked="{{chRating(5)}}"
                                                   ng-model="comment.rating">5</label>
            </div>
        </div>
        <div class="form-group"
             ng-class="{'has-error': commentForm.comment.$error.required && !commentForm.comment.$pristine}">
            <label class="col-sm-2 control-label">Your Comments</label>

            <div class="col-sm-10">
                <textarea class="form-control" id="comment" ng-model="comment.comment" name="comment" rows="12"
                          required></textarea>
                <span ng-show="commentForm.comment.$error.required && !commentForm.comment.$pristine"
                      class="help-block">Your comments are required.</span>
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-10 col-sm-offset-2">
                <button type="submit" name="button" class="btn btn-primary"
                        ng-disabled="commentForm.$invalid">Submit Comment
                </button>
            </div>
        </div>
    </form>
</div>