динамическая маршрутизация с элементом массива в angularjs после фильтрации массива

У меня проблема с моим приложением angularjs, когда мое приложение перенаправляется на неправильную страницу при использовании массива ng-repeat для определения маршрута.

данные выглядят так и доступны в контроллере person:

[
  {
    "name":"AJ lastname",
    "img_name":"AJ_lastname",
    "location":"Baltimore, Maryland",
    "info":"stuff"
  },
  {
    "name":"Albert lastname",
    "img_name":"Albert_lastname",
    "location":"Boston, Massachusetts",
    "info":"stuff"
  } // ... more data
]

html: (тег привязки ссылается на человека на основе его индекса в массиве (я считаю, что это может быть то, что мне нужно изменить, чтобы решить проблему, но я не уверен)

<ul class="main-list">
  <li class="list-item fade" ng-repeat="student in students | filter:filter">
    <a href="/#person/{{$index}}">
    <img class="portrait listimg" ng-src="/images/{{student.img_name}}.jpg" alt="portrait of {{student.name}}">
    <h2>{{student.name}}</h2>
    <h4>{{student.location}}</h4>
    </a>
  </li>
</ul>

Маршрутизация из angular: (маршрут с '/ person /: itemId' направляется на страницу, специфичную для конкретного пользователя, где их индекс в массиве определяет их идентификатор)

app.config(function ($routeProvider, $httpProvider) {
  $routeProvider
    .when('/list', {
      templateUrl: './js/templates/list.html',
      controller: 'ListController'
    })
    .when('/person/:itemId', {
      templateUrl: './js/templates/person.html',
      controller: 'PersonController'
    })
    .otherwise('/list');
});

Вот контроллер динамической страницы. Он отлично работает с исходным массивом, но как только я пытаюсь отсортировать массив, индекс больше не соответствует правильному ученику.

app.controller('PersonController', function ($scope, $http, $routeParams) {
  $scope.person = 'Someone\'s name';
  $http.get('../js/students.json').success(function (data) {
    $scope.allStudents = data;
    $scope.studentId = $routeParams.itemId;
    $scope.student = data[$scope.studentId];
  });

Таким образом, функциональная проблема заключается в том, что индекс применяется к первому студенту в большом массиве данных. Кажется, он работает отлично, и правильные данные заполняют страницу, но когда я использую ввод html / text для фильтрации списка, исходные индексы обновляются на стороне html, и они не соответствуют исходному массиву. Таким образом, маршрутизация отправляет их не на ту страницу.

Как заставить работать маршрутизацию даже для отфильтрованного списка?


person jmancherje    schedule 04.01.2016    source источник
comment
всегда используйте уникальный идентификатор, который остается постоянным для каждого элемента   -  person charlietfl    schedule 05.01.2016


Ответы (2)


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

$scope.getIndex = function(student) {
    return $scope.students.indexOf(student);
}

Затем вы можете вызвать функцию из своего списка, например:

<a ng-href="/#person/{{getIndex(student)}}">

Однако это не самый производительный код, который вы можете себе представить.

Другой способ - просто временно сохранить индекс учащегося как свойство и использовать его для ссылки на него, что опять же не самое лучшее решение:

$scope.students = $scope.students.map(function(student, index) {
    student.index = index;

    return student;
});

И в списке:

<a ng-href="/#person/{{student.index}}">

Однако, если вы можете каким-то образом назначить учащимся уникальный идентификатор, это определенно будет предпочтительным способом. Таким образом, вы также убедитесь, что всегда ссылаетесь на одного и того же ученика. Если ваш students.json каким-то образом изменится между временем, когда вы создаете список, и тем временем, когда пользователь нажимает на элемент, вы можете снова сослаться не на тот ...

Кстати, всегда используйте ng-href при включении заполнителей в ссылку. Почему вам следует это сделать, хорошо описано в документации по Angular API:

Использование разметки Angular, такой как {{hash}} в атрибуте href, приведет к тому, что ссылка перейдет на неправильный URL, если пользователь щелкнет ее до того, как Angular сможет заменить разметку {{hash}} ее значением. Пока Angular не заменит разметку, ссылка будет неработающей и, скорее всего, вернет ошибку 404. Директива ngHref решает эту проблему.

person Marcel Gwerder    schedule 05.01.2016

Вы создаете ng-repeat, используя некоторый объект в $ scope, называемый студентами, верно? Если он создается из того же файла student.json, что и в вашем контроллере, то их идентификаторы студентов должны быть логически эквивалентны. Поэтому просто измените href с "/ # person / {{$ index}}" на "/#person/{{student.studentId}}".

Если по какой-то причине они не совпадают, тогда, когда вы создаете объект студентов, вы можете добавить новый атрибут studentId, который содержит значение их индекса в массиве, а затем использовать предыдущее предложение.

Просто помните, что при использовании ng-repeat, если у вас есть идентичные объекты, он выдаст ошибку, поэтому вам нужно добавить к нему «трек по $ index».

person DanielC    schedule 05.01.2016