简体   繁体   English

过滤数组后在angularjs中使用数组项进行动态路由

[英]dynamic routing with array item in angularjs after filtering array

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. 我的angularjs应用出现问题,其中使用ng-repeat数组确定路由时,我的应用路由到错误的页面。

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) html:(anchor标签根据其在数组中的索引链接到该人(我相信这可能是我需要更改以解决此问题的方法,但我不确定)

<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) 从角度路由:(带有'/ person /:itemId'的路由正在路由到特定用户的页面,在页面中其索引在数组中确定其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. 它似乎工作正常,并且正确的数据填充了页面,但是当我使用html / text输入过滤列表时,原始索引在html侧更新,并且它们不对应于原始数组。 So the routing sends them to the wrong page. 因此,路由会将它们发送到错误的页面。

How can I make the routing work even for a filtered list? 即使对于过滤列表,我如何使路由工作?

You are creating the ng-repeat using some object on $scope called students, correct? 您正在$ scope上使用某个称为学生的对象创建ng-repeat,对吗? If this is being built from the same students.json as in your controller then their student ids should logically be equivalent. 如果这是从与控制器中相同的students.json构建的,则逻辑上他们的学生ID应该等效。 So just change the href from "/#person/{{$index}}" to "/#person/{{student.studentId}}". 因此,只需将href从“ /#person / {{$ index}}”更改为“ /#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. 如果由于某些原因它们不相同,那么当您创建students对象时,您可以添加一个新属性StudentId,该属性将其索引值保存在数组中,然后使用之前的建议。

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. 只要记住,当使用ng-repeat时,如果您具有相同的对象,则会抛出错误,因此必须在其中添加“ track by $ index”。

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 . 做到这一点的一种方法是使用一个函数,该函数为您的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. 但是 ,如果您可以通过某种方式为学生分配唯一的ID,那么这绝对是首选方法。 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... 如果您的students.json在创建列表的时间与用户单击某项的时间之间有所变化,则可能会再次引用错误的内容...

By the way always use ng-href when including placeholders in the link. 顺便说一句,当在链接中包含占位符时,请始终使用ng-href Why you should do so is well described in the Angular API docs : 为何要这样做,在Angular API文档中已进行了详细说明

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. 在href属性中使用{{hash}}之类的Angular标记会使链接转到错误的URL,前提是用户在Angular有机会用其值替换{{hash}}标记之前单击链接。 Until Angular replaces the markup the link will be broken and will most likely return a 404 error. 在Angular替换标记之前,链接将断开,并且很可能会返回404错误。 The ngHref directive solves this problem. ngHref指令解决了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM