Обновление AngularJS ng-repeat с новым вызовом API - PullRequest
0 голосов
/ 29 июня 2018

В настоящее время работаю над приложением, в котором я выполняю вызов API для получения данных, а затем использую директиву ng-repeat для заполнения таблицы в представлении.

<tr md-row ng-repeat="request in requests">
        <td md-cell>{{request.name}}</td>
        <td md-cell>{{request.email}}</td>
        <td md-cell>{{request.application_name}}</td>
        <td md-cell>{{request.created_user}}</td>
        <td md-cell>{{request.request_type}}</td>
        <td md-cell>{{request.status}}</td>
</tr>

И в контроллере пользователь делает новый запрос и добавляет строку в базу данных, и после появления диалога об успешном выполнении я хочу сделать новый запрос к API, чтобы получить новую строку, сгенерированную сервером, поэтому я хочу сделать новый запрос API.

Итак, я связываюсь с API и снова получаю все запросы и хочу заменить данные в таблице на обновленные данные из API

Когда вызов API успешен, он вызывает эту функцию из обещания:

var onRequests = function(response) {
  $scope.requests = [];

      response.forEach(function() {
          //Processing here and pushing to the new array
      });
  });
};

Но при создании этого нового массива я предполагаю, что ссылка на исходный массив, который имеют области действия частей ng-repeat, потеряна.

Итак, я пытаюсь найти способ обновить таблицу ng-repeat новым массивом.

Вот что я пробовал:

  • Новый массив, а затем $apply ing

  • Сохранение той же ссылки на массив и просто удаление всего и выполнение это снова, но это похоже на хакерский путь, и я хочу элегантный решение

  • Использование $ rootScope вместо массива, который, похоже, работает для некоторых причина ...

Вот как я сделал $ rootScope, который работает (но кажется хакерским):

 var onRequests = function(response) {
      $rootScope.requests = [];

          response.forEach(function() {
              //Processing here and pushing to the new array
          });
      });
    };

По какой-то причине это работает , и я не знаю, почему это работает. Вот почему я не понимаю.

Проблема : Когда я выполняю вызов API, вызывается эта функция, и $scope.requests устанавливается в пустой массив (это изменяет адрес / теряет ссылки?), А затем заполняется новые данные из API. Мне интересно, если это не обновляет дочерние области ng-repeat с новыми данными .

Я знаю, что обычно, если вы измените массив ng-repeat $scope, он должен обновить DOM, но, поскольку я устанавливаю его в пустой и новый массив, а затем заполняю этот новый массив, кажется, он теряет ссылка на массив. Вот почему это работает, если я иду и вставляю каждый элемент в массив, а не просто устанавливаю его равным совершенно новому пустому массиву (например, $scope.requests = [];


Что я хочу

Независимо от того, является ли это лучшим способом ее решения. Все, что я хочу сделать , это обновить таблицу ng-repeat новыми данными из вызова API.

Если бы кто-нибудь мог мне помочь, это было бы здорово. Я перечитывал другие похожие вопросы и, похоже, не нашел ничего полезного или точного в том, что я пытаюсь сделать, из того, что я нашел, это не сработало.

РЕДАКТИРОВАТЬ: Просто чтобы прояснить, я перечитал около дюжины других постов с похожей формулировкой, и ни один не был точным в соответствии с тем, что я пытаюсь сделать, как я сказал, поэтому перед тем, как помечать как дубликат Знайте, что многие другие не работали как решения.

1 Ответ

0 голосов
/ 30 июня 2018

Похоже, это ваш вопрос:

Итак, я пытаюсь найти способ обновить таблицу ng-repeat. с новым массивом.

Краткий ответ таков:

$scope.requests = newArrayOfRequests;

Или то, что у тебя тоже работает:

//clear the array. I don't why you would need a reference to the old array,
// but if you do, then
//$scope.old = requests;
//then
$scope.requests = [];

response.forEach(function() {
  // do your processing
  $scope.requests.push(processedRow)
});

Вот и все. В AngularJS это все, что вам нужно сделать. Это магия связывания AJS.

Теперь есть некоторые улучшения производительности, которые вы можете сделать, используя track by в сочетании с вашим ng-repeat. Но это все, что вам нужно сделать, чтобы обновить ng-repeat.

Более длинный ответ связан с узлами DOM. AJS DOE INDEED отслеживает каждую вещь, добавляемую к ngRepeat, используя общие идентификаторы, которые она создает (если вы просматриваете свою таблицу в инструментах разработки, вы можете фактически увидеть эти идентификаторы как атрибуты). Однако это не поможет вам, если эти идентификаторы не могут быть сопоставлены с вашими данными. К счастью, вы можете указать, что он использует уникальный идентификатор из фактических данных, используя track by:

<tr md-row ng-repeat="request in requests track by request.some_unique_id">
        <td md-cell>{{request.name}}</td>
        <td md-cell>{{request.email}}</td>
        <td md-cell>{{request.application_name}}</td>
        <td md-cell>{{request.created_user}}</td>
        <td md-cell>{{request.request_type}}</td>
        <td md-cell>{{request.status}}</td>
</tr>

Это позволяет AJS повторно использовать узлы DOM, которые он ранее создал с первой загрузки данных, вместо того, чтобы воссоздавать их каждый раз при загрузке новых данных.

Когда вы загружаете новый массив, AJS должен только обновить значение каждой строки, или, в вашем случае, он должен добавить только один узел DOM для новой строки, возвращаемой API

Но это не меняет способ обновления данных. Просто назначьте новый массив переменной $scope или очистите его и отправьте новые данные. Это все, что нужно сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...