过滤数组

时间:2016-01-04 23:40:25

标签: javascript angularjs angularjs-filter mvw

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

从角度路由:(带有&#39; / person /:itemId&#39;的路由将路由到特定用户的页面,其中数组中的索引确定其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端更新,并且它们与原始数组不对应。因此路由将它们发送到错误的页面。

如何对路由列表进行路由工作?

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分: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 docs

中有详细描述
  

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