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

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

我一直在 Coursera 上学习 Angular JS 的类(class),我遇到了 ng-repeat 在我使用表单将某些内容推送到数组后没有更新我的 View 的问题。当我在提交表单后尝试记录数组的内容时,似乎一切都是正确的(元素被推送到数组上,但我的 View 没有刷新以反射(reflect)此更改。

两天来我一直在努力解决这个问题,但由于我仍然无法解决并且我被卡住了,我将在这里发布我的部分代码,我希望有人可以帮助我修复它并且了解发生了什么。

    <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:""};
        }
    }]);

我希望有人能帮我解决这个问题。提前谢谢你。

最佳答案

只需将您的父 Controller ,即 DishDetailController 放入父级 div,即 ng-controller="DishDetailController" 中,以便 DishCommentController 可以继承DishDetailController Controller 的作用域。

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

例如运行下面的例子:

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>

关于javascript - 将对象推送到数组时 ng-repeat 不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34284718/

相关文章:

javascript - 我们如何使用 JavaScript 拖动和移动图像?

javascript - 当我通过 document.getElementById 更新值时,React 不会触发 onChange 事件

javascript - HighChart 使用小数据集呈现空白

php - 具有自定义索引 PHP 的 Foreach

javascript - Angular JS显示div元素时出现问题

javascript - 强制重新加载指令模板

javascript - Chart.js Line,负点的不同填充颜色

arrays - 带数组的 Groovy 简单函数

javascript - 为什么这个 for 循环需要这么长时间?

javascript - Typescript Angular ui 引导模式