AngularJS - espaço reservado para resultado vazio do filtro

95

Quero ter um marcador de posição, por exemplo, <No result>quando o resultado do filtro retornar vazio. Alguém poderia ajudar? Eu nem sei por onde começar ...

HTML :

<div ng-controller="Ctrl">
<h1>My Foo</h1>
<ul>
    <li ng-repeat="foo in foos">
        <a href="#" ng-click="setBarFilter(foo.name)">{{foo.name}}</a>
    </li>
</ul>
<br />
<h1>My Bar</h1>
<ul>
    <li ng-repeat="bar in bars | filter:barFilter">{{bar.name}}</li>
</ul>

</div>

JS :

function Ctrl($scope) {

  $scope.foos = [{
    name: 'Foo 1'
  },{
    name: 'Foo 2'
  },{
    name: 'Foo 3'
  }];

  $scope.bars = [{
    name: 'Bar 1',
    foo: 'Foo 1'
  },{
    name: 'Bar 2',
    foo: 'Foo 2'
  }];

  $scope.setBarFilter = function(foo_name) {
    $scope.barFilter = {};
    $scope.barFilter.foo = foo_name;
  }
}

jsFiddle : http://jsfiddle.net/adrn/PEumV/1/

Obrigado!

Adrian Gunawan
fonte
ah sim, bom truque com o ng-show. Muito obrigado
Adrian Gunawan

Respostas:

252

Um ajuste na abordagem que exige que você especifique o filtro apenas uma vez:

  <li ng-repeat="bar in filteredBars = (bars | filter:barFilter)">{{bar.name}}</li>
</ul>
<p ng-hide="filteredBars.length">Nothing here!</p>

Violino

Mark Rajcok
fonte
6
Esta é a solução mais agradável, pois você só precisa declarar seu filtro uma vez. +1
Tim B James
1
O problema é que a mensagem "Nada aqui!" parte é mostrada e escondida muito rapidamente. Quando você obtém dados com uma solicitação ajax, há um atraso antes que os dados retornados sejam mostrados e, nesse tempo, você pode ver a mensagem "Nada aqui!" parte aparecem e desaparecem.
Temega
@Temega - você poderia adicionar uma classe "ng-hide" ao div
Brian Oliver
3
@Temega Você poderia usar ng-show = "
filterBars.length
Eu uso ng-controller = "FooController como $ ctrl" e "bar em $ ctrl.filteredBars = (bars | filter: barFilter)" então eu poderia usar $ ctrl.filteredBars.length fora do ng-repeat. Obrigado por esta dica épica!
xlttj
37

Aqui está o truque para usar o ng-show

HTML:

<div ng-controller="Ctrl">
<h1>My Foo</h1>
<ul>
    <li ng-repeat="foo in foos">
        <a href="#" ng-click="setBarFilter(foo.name)">{{foo.name}}</a>
    </li>
</ul>
<br />
<h1>My Bar</h1>
<ul>
    <li ng-repeat="bar in bars | filter:barFilter">{{bar.name}}</li>
</ul>
<p ng-show="(bars | filter:barFilter).length == 0">Nothing here!</p>

</div>

jsFiddle: http://jsfiddle.net/adrn/PEumV/2/

Adrian Gunawan
fonte
2
Mas neste caso o filtro é executado duas vezes, existe uma maneira de evitar isso?
Isaías
Obrigado por esta solução. Tenho usado o filtro groupBy fornecido aqui github.com/a8m/angular-filter, mas infelizmente a resposta aceita acima não funciona. Este método pode executar o filtro duas vezes, mas resolveu o problema de qualquer maneira.
Anthony
No meu caso funciona sem o "== 0". <p ng-show = "(bars | filter: barFilter) .length"> Nada aqui! </p>
Alessio
22

Tirado deste documento oficial, é assim que eles fazem:

ng-repeat="friend in friends | filter:q as results"

Em seguida, use os resultados como uma matriz

<li class="animate-repeat" ng-if="results.length == 0">
  <strong>No results found...</strong>
</li>

Snippet completo:

<div ng-controller="repeatController">
I have {{friends.length}} friends. They are:
<input type="search" ng-model="q" placeholder="filter friends..." aria-label="filter friends" />


<ul class="example-animate-container">
    <li class="animate-repeat" ng-repeat="friend in friends | filter:q as results">
      [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
    </li>
    <li class="animate-repeat" ng-if="results.length == 0">
      <strong>No results found...</strong>
    </li>
  </ul>
</div>
caiocpricci2
fonte
4
Suspeito que as coisas mudaram desde que essa pergunta foi feita pela primeira vez, mas como atualmente é exatamente como os documentos do Angular sugerem que você resolva o problema, eu diria que este é o caminho certo a seguir neste ponto.
jackel414
1
Não consegui encontrar outro exemplo. Isto está “escondido” na documentação da animação e por acaso o reparei no mesmo dia que precisei ou acho que não teria lembrado.
caiocpricci2