Присвойте значение каждому объекту в массиве без цикла - PullRequest
0 голосов
/ 16 мая 2018

Я добавляю простой комментирующий компонент в приложение angular 1. Объект, который я получаю с сервера, выглядит так:

comments":[
        {"id":1,"content":"this is my first comment","approved":1,"replies":[]},
        {"id":2,"content":"this is the second","approved":1,"replies":[
          {"priority_id":0,"content":"content of a reply","approved":1},
          {"priority_id":0,"content":"content of a second reply","approved":1}]
        }
      ]

В данный момент я использую 2 цикла в контроллере, чтобы присвоить «ожидающее» значение каждому комментарию и ответу, получив одобрение: 0

Это выглядит так:

angular.forEach($scope.comments, function (comment) {
          if (comment.approved === 0) {
            comment.pending = true;
        }
          comment.replies = comment.replies || [];

          angular.forEach(comment.replies, function (reply) {
          if (reply.approved === 0) {
            reply.pending = true;
            }
          });
      });

Есть ли лучший, более короткий способ получить это? Javascript не совсем моя сильная сторона. Мне действительно нужно зациклить в контроллере? Может я могу как-то передать значение из ng-repeat? Заранее спасибо!

Благодаря Джо Я узнал лучший способ, чем зацикливание. Я отметил его ответ как решение, хотя мне пришлось немного изменить код, чтобы он работал, потому что мое приложение использует угловой 1.4, который несовместим с функциями стрелок. Вот код:

$scope.comments.map(function(comment) {

                  if (comment.approved === 0) {
                    comment.pending = true;
                  }

                  comment.replies = comment.replies || [];

                  comment.replies.map(function(reply){
                     if (reply.approved === 0) {
                    reply.pending = true;
                    }
                    return reply.approved;
                  });
                  return comment.approved;

                });

Он не выглядит так аккуратно, как у Джо, но он все еще использует метод карты, который, как предложили Джо и Мэтью, лучше, чем зацикливание.

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Вы можете написать функцию, которая добавляет этот ключ к вашим объектам. С помощью этой функции ваши циклы будут выглядеть так:

let comments = [{
  "id": 1,
  "content": "this is my first comment",
  "approved": 1,
  "replies": []
}, {
  "id": 2,
  "content": "this is the second",
  "approved": 1,
  "replies": [{
      "priority_id": 0,
      "content": "content of a reply",
      "approved": 1
    },
    {
      "priority_id": 0,
      "content": "content of a second reply",
      "approved": 1
    }
  ]
}, {
  "id": 3,
  "content": "this is the third",
  "approved": 0,
  "replies": [{
      "priority_id": 0,
      "content": "content of a reply",
      "approved": 0
    },
    {
      "priority_id": 0,
      "content": "content of a second reply",
      "approved": 0
    }
  ]
}];

function AddPending(obj) {
  obj['pending'] = true;
  return obj;
}

comments.forEach(function(comment) {

  comment = (comment.hasOwnProperty('approved') && comment.approved === 0) ? AddPending(comment) : comment;


  comment.replies = comment.replies || [];

  comment.replies.forEach(function(reply) {
    reply = (reply.approved === 0) ? AddPending(reply) : reply;
  });
});

console.log(comments);

Также вы можете обновить эту функцию, которая получает объект и проверяет условие, и если условие истинно, добавьте ключ. Используйте эту функцию на ng-repeat. как ниже

var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
  $scope.comments = [{
    "id": 1,
    "content": "this is my first comment",
    "approved": 1,
    "replies": []
  }, {
    "id": 2,
    "content": "this is the second",
    "approved": 1,
    "replies": [{
        "priority_id": 0,
        "content": "content of a reply",
        "approved": 1
      },
      {
        "priority_id": 0,
        "content": "content of a second reply",
        "approved": 1
      }
    ]
  }, {
    "id": 3,
    "content": "this is the third",
    "approved": 0,
    "replies": [{
        "priority_id": 0,
        "content": "content of a reply",
        "approved": 0
      },
      {
        "priority_id": 0,
        "content": "content of a second reply",
        "approved": 0
      }
    ]
  }];

  function AddPending(obj) {
    obj['pending'] = true;
    return obj;
  }

  $scope.f = function(comment) {
    comment = (comment.approved === 0) ? AddPending(comment) : comment;
    comment.replies = comment.replies || [];

    angular.forEach(comment.replies, function(reply) {
      reply = (reply.approved === 0) ? AddPending(reply) : reply;
    });
    return comment;
  };

});
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>
<script src="script.js"></script>

<body>

  <div ng-app="myApp" ng-controller="myCtrl">
    <hr>
    <div ng-repeat="comment in comments track by $index">
      comment: {{f(comment)}}
      <hr>

    </div>

  </div>
</body>

</html>
0 голосов
/ 16 мая 2018

Так что не уверен, что это более понятно или просто более сжато, но вы можете воспользоваться прототипом javascript .map для массивов.Функция map выполняет итерацию по массиву и преобразует каждое значение в новое, в зависимости от предоставленной функции.Так что это фактически вернет новый массив объектов, сопоставленных с предыдущим массивом.Я не уверен, что это действительно проще.Вы также можете воспользоваться функциями стрелок ES5.

Еще одна вещь: в вашем текущем коде комментарий получает ожидающее поле только в том случае, если одобрено === 0. Это означает, что если не равно 0,ожидающее поле не будет существовать в комментарии.Это может привести к странным вещам позже, если вы полагаетесь на это поле.Некоторые скажут, что ожидание равно true, в то время как другие комментарии будут неопределенными.Это также верно для ваших ответов.Мое решение, приведенное ниже, использует условие КАК поле ожидания, чтобы оно существовало для каждого объекта, а не только для истинных.

MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

$scope.comments.map(comment => {
    comment.pending = comment.approved === 0;
    comment.replies = (comment.replies || []).map(reply => {
        reply.pending = reply.approved === 0;
        return reply;
    });
    return comment;
})
...