dynamic routing with array item in angularjs after filtering array

扶醉桌前 提交于 2019-12-11 11:32:15

问题


I have a problem with my angularjs app where my app is routing to the wrong page when using an ng-repeat array to determine the route.

data looks like this and is accessed in the person controller:

[
  {
    "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: (the anchor tag links to the person based on their index in the array (I believe this may be what I need to change to fix the problem, but I'm not sure)

<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>

Routing from angular: (the route with '/person/:itemId' is routing to a page specific to a specific user, where their index in the array determines their id)

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');
});

Here is the controller for the dynamic page. It works perfectly for the original array, but once I attempt to sort the array, the index no longer corresponds to the correct student.

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

So the functional problem is that the index applies to the first student in the large array of data. It appears to work perfectly, and the correct data populates the page, but when I use the html/text input to filter the list, the original indices are updated on the html side, and they do not correspond to the original array. So the routing sends them to the wrong page.

How can I make the routing work even for a filtered list?


回答1:


One way you can do this is by using a function which returns you the index a student had in the original array for each student in your ng-repeat.

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

You can then call the function in your list like:

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

This though is not quite the most performant code you could imagine.

Another way would be to just temporarily store the index of the student as a property and use that one to reference it, again not quite the nicest solution:

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

    return student;
});

And in the list:

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

However, if you can somehow assign the students a unique id that would definitely be the preferred way. That way you also make sure that you always reference the same student. If your students.json somehow changes between the time you create the list and the time the user clicks on an item you may reference the wrong one again...

By the way always use ng-href when including placeholders in the link. Why you should do so is well described in the Angular API docs:

Using Angular markup like {{hash}} in an href attribute will make the link go to the wrong URL if the user clicks it before Angular has a chance to replace the {{hash}} markup with its value. Until Angular replaces the markup the link will be broken and will most likely return a 404 error. The ngHref directive solves this problem.




回答2:


You are creating the ng-repeat using some object on $scope called students, correct? If this is being built from the same students.json as in your controller then their student ids should logically be equivalent. So just change the href from "/#person/{{$index}}" to "/#person/{{student.studentId}}".

If for some reason they aren't the same then when you create the students object you can add a new attribute, studentId, which holds the value of their index in the array and then use the previous suggestion.

Just remember that when using ng-repeat if you have identical objects it'll throw an error so you have to add the "track by $index" to it.



来源:https://stackoverflow.com/questions/34601851/dynamic-routing-with-array-item-in-angularjs-after-filtering-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!