Пользовательские фильтры Angularjs (Фильтрация массива объектов) - PullRequest
0 голосов
/ 27 декабря 2018

Я делаю веб-приложение, используя angularjs.У меня есть список сообщений, полученных из серверной части в следующей структуре:

[
  {
    post: {
      postID: 1,
      title: "sample title", 
      body: "so many paragraphs here", 
      post_date: "2018-12-26 02:21:35"
    } 
    tags: [
      {
        tagTitle: "training"
      }, 
      {
        tagTitle: "another tag" 
      } 
    ] 
  } 
]

Я хочу отфильтровать эти сообщения в соответствии с тегом, по которому я нажал.Скажем, я нажал на тренинг, и я хочу отображать посты, которые имеют запись training в их массиве tags .

Поскольку это веб-приложение angularjs,ui-sref - это сообщения (фильтр: «обучение»), а путь (URL) будет сообщения? фильтр = обучение.

Я создал фильтр со следующим кодом:

function postsFilter() {
  return function (collection, params) {
    return collection.filter(function (item) {
      var i, tagsArray = item.tags, len = tagsArray.length;
      for (i = 0; i < len; ++i) {
        return tagsArray[i].tagTitle === (
          params.filter === "none" ? tagsArray[i].tagTitle : 
            params.filter;) 
        } 
    });
  };
}

angular.module('app').filter('postsFilter', postsFilter);

В контроллере у меня есть следующий код:

function PostsController($filter) {
  angular.extend(this, {
    $onInit: () => {
      this.filteredPosts = $filter('postsFilter')(this.posts, this.filter);
    } 
  } 
}

В компоненте у меня есть следующий код:

const posts = {
  bindings: {
    posts: '<', 
    filter: '<' 
  }, 
  templateUrl: 'path/to/my/posts.html',
  controller: 'postsController'
};

angular.module('app').component('posts', posts).config(
[
  '$stateProvider', function ($stateProvider) {
    $stateProvider.state (
      'posts', {
        url: '/posts?filter',
        component: 'posts', 
        params: {
          filter: {
            value: 'none'
          }
        }, 
        resolve: {
          posts: ['PostsService', function (PostsService) {
            return PostsService.getPostList();
        }],
        filter: ['$transition$', function ($transition$) {
          return $transition$.params();
        }]
      } 
    }
  );
  } 
]);

В файле posts.html я хочу отобразить отфильтрованные сообщениянапример:

<div ng-repeat='post in $ctrl.filteredPosts'>
  {{post.post.title}}
</div>

С моим текущим кодом, когда я нажимаю на ссылку для фильтрации сообщений (скажем, ui-sref = 'posts ({filter:' angularjs '})), сообщения неотфильтроватьURL-адрес изменяется, но сообщения все равно отображают все сообщения.По умолчанию в URL для сообщений отображается / posts? Filter = none .Когда я нажимаю на ссылку, чтобы отфильтровать записи (скажем, тег angularjs), URL-адрес меняется на / posts? Filter = angularjs .

Как мне исправить это?

ОК, теперь он работает после установки этих пропущенных фигурных скобок.Теперь у меня проблема в том, что если сообщение имеет два или более тегов, я не могу отфильтровать его с другими тегами, оно работает только с первым тегом.

В этом примере это будет толькофильтруется с помощью training , он не фильтруется с другим тегом .. Есть идеи, как заставить это работать?

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

если сообщение имеет два или более тегов, я не могу отфильтровать его с другими тегами, оно работает только с первым тегом

Вы можете попробовать сформировать URl следующим образом

posts? Filter = angularjs & training

А затем в функции фильтра сформируйте массив тегов фильтра.Таким образом, у вас будет два массива - Коллекция и Фильтры.Теперь используйте javascript Array Включает функцию для каждого фильтра в массиве Filters.Пример ниже (вам нужно настроить его в соответствии со структурой вашей модели):

let filteredCollection = new Array();
filters.foreach((filter) => {
  if(collection.includes(filter)) {filteredCollection.push(collection)}
})

Хотя это включает в себя разбор двух массивов каждый раз, но это самое быстрое решение под рукой.

0 голосов
/ 28 декабря 2018

Я решил проблему сам.Я изменил код фильтра на следующий (и теперь он работает отлично).

function postsFilter () {
return function (collection, params) {
return collection.filter(function (item) {
var i, tagArray = item.tags, len = tagArray.length;
for (i = 0; i < len; ++i) {
if (params.filter === tagArray[i].tagTitle) {
return tagArray[i].tagTitle === (
params.filter === 'none' ? tagArray[i].tagTitle : params.filter
);
} else if (params.filter === 'none') {
return tagArray[i].tagTitle === (
params.filter === 'none' ? tagArray[i].tagTitle : params.filter
);
} 
} 
}
} 
}

Это делает то, что я хотел, но мне не нравится то, что я сделал.Я повторил код.Если кто-то может помочь сделать это DRY , это было бы здорово.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...