how to filter an ngRepeat loop according to the value of one of the contents of an array

4

Well, the content of a page on my site is generated from the following JSON template:

[
  {
    "company":{
      "name":"Nome do Cliente",
      "url":"#"
    },
    "client":{
      "name":"Projeto",
      "url":"#"
    },
    "tags":[
      "tag1",
      "tag2",
      "tag3"
    ],
    "description":"Lorem Ipsum",
    "image":"#"
  }
]

And then it looks like this:

<div class="row portfolio-item" ng-repeat="project in projects">
    <div class="image hidden-sm hidden-xs col-md-6">
        <img class="layout" src="{{project.image}}">
        <span class="mask"></span>
    </div>
    <section class="col-md-6 col-sm-12 col-xs-12 portfolio-content">
        <header>
            <h2>{{project.company.name}}/{{project.client.name}}</h2>
            <nav class="tags">
                <a ng-repeat="tag in project.tags" href="/tag/{{tag}}">{{tag}}</a>
            </nav>
        </header>
        <article>
            <p>{{project.description}}</p>
        </article>
    </section>
</div>

However, I would like to be able to filter the content displayed according to the tag selected. I tried to use the filter:tag attribute, but the angle does not return me result. ('tag' was defended with a scope variable in the controller with one of the values of the 'tags' array of JSON)

    
asked by anonymous 16.12.2014 / 21:30

4 answers

2

Well, based on the answer from @Pedro Luz and on this response , I came up with the following code that solved my problem :

.filter('filterBySelectedTag', function() {
    return function(projects, selectedTag){
        if(selectedTag == null){
            var filtered = projects;
        }else{
            var filtered = [];
            angular.forEach(projects, function(project) {
                angular.forEach(project.tags, function(tag){
                    if( tag == selectedTag )
                        filtered.push(project);
                });
            });
        }
        return filtered;
    }
});
    
17.12.2014 / 12:12
0

As the @Pedro Light replied, the idea is right, going in the use of Angular filters, but they are used differently.

For example, do I want to change the way a date is displayed?

I use the following Angular binding:

{{ date | (filtro aqui) }}

Exemplifying:

{{ date | dd }}

That would return the day in numerical format (17, as today is December 17).

    
17.12.2014 / 00:10
0

Matthew, I do not know if that's exactly what you need ... but in one of my projects I have a ng-repeat in JSON and I put some filters on from values typed in <input> . Example below:

<table>
  <thead>
    <tr>
      <th>#</th>
      <th>
        <input type="text" ng-model="search.contactName">
        Nome do contato
      </th>
    </tr>
  </thead>

  <tbody>
    <tr ng-repeat="item in filtered = (list | filter:{contactName: search.contactName })">
      <td>
        <strong>[[ $index + 1 ]]</strong>
      </td>
      <td>[[ item.contactName ]]</td>
    </tr>
  </tbody>
</table>
    
18.12.2014 / 18:38
0

Man, I would advise you not to rewrite the wheel, because then the maintenance would be horrible. In your specific case, you just need to do the following

<div ng-repeat="tag in tags | filter: { property: valor }"></div>

It gets much cleaner and organized without having to declare any filters. In that case, I passed an object to the filter, not just a value

Example: Imagine a div where you want to filter the active items, in which case it would be

<div ng-repeat="item in items | filter: { active: true}">
      <span>{{ item.qualquer_coisa }}</span>
</div>
    
19.12.2014 / 13:56