Почему мой вложенный объект возвращается неопределенным при циклическом прохождении? - PullRequest
0 голосов
/ 15 апреля 2019

https://plnkr.co/edit/aZi06HM9CkM9lScy9LS3?p=preview

$scope.lettersandthings = [
   { letter: "a", things: [{name:"airplane"}, {name:"apple"}, {name:"alligator"}]}, 
   { letter: "b", things: [{name:"bath"}, {name:"bicycle"}, {name:"bear"}]},
   { letter: "c", things: [{name:"chair"}, {name:"carrot"}, {name:"cat"}]}
 ]; 

$scope.allchildrenLength = 9;
$scope.allparentsLength = 3;

ng-click="myFunction(0)" <!-- indexParent -->
ng-click="myFunction(1)"
ng-click="myFunction(2)"

for(i=0; i < $scope.allchildrenLength; i++) {
    for(var j=0; j < $scope.allparentsLength; j++)  {
      $scope.lettersandthings[j].things[i].open = !$scope.lettersandthings[indexParent].open || $scope.lettersandthings[j].open ? false : $scope.lettersandthings[j].things[i].open;
    }
  }

Этот раздел myFunction() дает мне ошибки (однако он все еще функционирует так, как должен):

  • TypeError: Невозможно прочитать свойство 'open' из неопределенного
  • TypeError: Невозможно установить свойство 'open' из неопределенного

Я читал, что вам нужно использовать цикл for ... in для доступа к вложенным объектам, но я не уверен, как именно это сделать для моего случая. Я пытался здесь, но я все еще получаю те же ошибки (и он перестал работать):

for(var lttr in $scope.lettersandthings) {
    for(var thng in $scope.lettersandthings[lttr]) {
      $scope.lettersandthings[lttr].things[thng].open = !$scope.lettersandthings[indexParent].open || $scope.lettersandthings[lttr].open ? false : $scope.lettersandthings[lttr].things[thng].open;
    }
  }

Несмотря на то, что он работает так, как должен, я бы хотел быть безошибочным. Спасибо.

Полный код:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>title</title>

    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    
    <style type="text/css">
      .section {
        margin: 20px;
        padding: 10px;
      }

     
    </style>

  </head>
  <body>
  
    <div ng-app="myApp" ng-controller="myCtrl">

      <script type="text/ng-template" id="group-template.html">
        <div class="panel-heading">
          <h4 class="panel-title" style="color:#fa39c3">
            <a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading">
              <span uib-accordion-header ng-class="{'text-muted': isDisabled}">
                {{heading}}
              </span>
            </a>
          </h4>
        </div>
        <div class="panel-collapse collapse" uib-collapse="!isOpen">
          <div class="panel-body" style="text-align: right" ng-transclude></div>
        </div>
      </script>

      <div class="section">
        <button ng-click="myFunction(0)">Toggle a</button>
          <button ng-click="lettersandthings[0].things[0].open = !lettersandthings[0].things[0].open">Toggle airplane</button>
          <button ng-click="lettersandthings[0].things[1].open = !lettersandthings[0].things[1].open">Toggle apple</button>
          <button ng-click="lettersandthings[0].things[2].open = !lettersandthings[0].things[2].open">Toggle alligator</button>
      </div>

      <div class="section">
        <button ng-click="myFunction(1)">Toggle b</button>
          <button ng-click="lettersandthings[1].things[0].open = !lettersandthings[1].things[0].open">Toggle bath</button>
          <button ng-click="lettersandthings[1].things[1].open = !lettersandthings[1].things[1].open">Toggle bicycle</button>
          <button ng-click="lettersandthings[1].things[2].open = !lettersandthings[1].things[2].open">Toggle bear</button>
       </div>

      <div class="section">
        <button ng-click="myFunction(2)">Toggle c</button>
          <button ng-click="lettersandthings[2].things[0].open = !lettersandthings[2].things[0].open">Toggle chair</button>
          <button ng-click="lettersandthings[2].things[1].open = !lettersandthings[2].things[1].open">Toggle carrot</button>
          <button ng-click="lettersandthings[2].things[2].open = !lettersandthings[2].things[2].open">Toggle cat</button>
      </div>


    <div id="accordion-wrapper">

      <uib-accordion close-others="oneAtATime">
          <div uib-accordion-group  id="accordion" ng-repeat="l in lettersandthings" heading="{{l.letter}}" class="eachLetter" id="{{l.id}}" is-open="l.open">

            <!-- nested accordion -->
            <uib-accordion close-others="oneAtATime">
              <div uib-accordion-group id="inner-accordion" class="innercontent" ng-repeat="thing in l.things" heading="{{thing.name}}" is-open="thing.open">
                <p>{{thing.name}} content</p>
              </div>  
            </uib-accordion>

          </div>
      </uib-accordion>  

    </div>


<script type="text/javascript">

  var myApp = angular.module('myApp', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);

  myApp.controller('myCtrl', function($scope) {

    $scope.oneAtATime = true;

    $scope.allchildrenLength = 9;
    $scope.allparentsLength = 3;

    $scope.myFunction = function(indexParent) {

    // First close the outer tab
    $scope.lettersandthings[indexParent].open = !$scope.lettersandthings[indexParent].open;

      // Close all inner tabs if the outer parent is closed or any other tab is opened
      for(i=0; i < $scope.allchildrenLength; i++) {
        for(var j=0; j < $scope.allparentsLength; j++)  {
          $scope.lettersandthings[j].things[i].open = !$scope.lettersandthings[indexParent].open || $scope.lettersandthings[j].open ? false : $scope.lettersandthings[j].things[i].open;
        }
      }
      
    }
  

    $scope.lettersandthings = [
       { letter: "a", things: [{name:"airplane"}, {name:"apple"}, {name:"alligator"}]}, 
       { letter: "b", things: [{name:"bath"}, {name:"bicycle"}, {name:"bear"}]},
       { letter: "c", things: [{name:"chair"}, {name:"carrot"}, {name:"cat"}]}
     ];    

  });

</script>



  </body>
</html>

1 Ответ

1 голос
/ 15 апреля 2019

Вы получаете доступ, например, things[3], но, несмотря на то, что у вас всего 9 вещей, каждый из ваших things массивов имеет длину всего 3 элемента, поэтому четвертый элемент (и все после этого до 9-го) равен undefined

Вы должны переключить внутренний и внешний цикл и проверить длину каждого things массива перед итерацией

for(j=0; j < $scope.allparentsLength; j++) { 
  for(i=0; i< $scope.lettersandthings[j]. things.length; i++) { 
    $scope.lettersandthings[j].things[i].open = !$scope.lettersandthings[indexParent].open || $scope.lettersandthings[j].open ? false : $scope.lettersandthings[j].things[i].open; 
  } 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...