1

我的 angularjs 应用程序出现问题,在使用 ng-repeat 数组确定路由时,我的应用程序路由到了错误的页面。

数据看起来像这样,并在人员控制器中访问:

[
  {
    "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>

从角度路由:(带有'/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');
});

这是动态页面的控制器。它对原始数组非常有效,但是一旦我尝试对数组进行排序,索引就不再对应于正确的学生。

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 端更新,它们与原始数组不对应。因此路由将它们发送到错误的页面。

即使对于过滤列表,我如何才能使路由工作?

4

2 回答 2

1

您正在使用 $scope 上名为 students 的某个对象创建 ng-repeat,对吗?如果这是从与您的控制器中相同的students.json 构建的,那么他们的学生ID 在逻辑上应该是等效的。因此,只需将 href 从“/#person/{{$index}}”更改为“/#person/{{student.studentId}}”即可。

如果由于某种原因它们不相同,那么当您创建学生对象时,您可以添加一个新属性 studentId,该属性保存数组中索引的值,然后使用前面的建议。

请记住,当使用 ng-repeat 时,如果您有相同的对象,它会抛出一个错误,因此您必须向其中添加“track by $index”。

于 2016-01-05T00:00:32.723 回答
1

您可以做到这一点的一种方法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}}">

但是,如果您可以以某种方式为学生分配一个唯一的 ID,那肯定是首选方式。这样,您还可以确保始终引用同一个学生。如果您students.json在创建列表的时间和用户单击某个项目的时间之间发生了某种变化,您可能会再次引用错误的项目...

顺便说一句ng-href,在链接中包含占位符时始终使用。为什么你应该这样做在Angular API 文档中有很好的描述:

在 href 属性中使用像 {{hash}} 这样的 Angular 标记,如果用户在 Angular 有机会将 {{hash}} 标记替换为其值之前单击它,则链接会转到错误的 URL。在 Angular 替换标记之前,链接将被破坏,并且很可能会返回 404 错误。ngHref 指令解决了这个问题。

于 2016-01-05T00:09:05.103 回答