【问题标题】:How can i show only results where card.column value matches column.id in angular2?如何仅显示 card.column 值与 angular2 中的 column.id 匹配的结果?
【发布时间】:2016-04-16 15:13:34
【问题描述】:

我有下面的代码,它工作正常,它的作用是 ngFor repeat 为列对象中的每一列创建一个列。

目前它在每一列中显示卡片对象中的每张卡片。

我想要它做的是只在 WHERE column.id = card.column 列中显示卡片

如何修改我的代码来做到这一点?

  import {Input, Output, EventEmitter, Component, Injectable} from 'angular2/core'
  import {NgFor} from 'angular2/common'
  import {Observable} from 'rxjs/Observable';

  interface Card {
    id?: number;
    title?: string;
    column?: number;
  }

  @Injectable()
  export class DataService {
    cards$: Observable<Array<Card>>;
    private _cardsObserver: any;
    private _dataStore: Array<Card>;

    constructor(){
      this._dataStore = [
        {id: 1, title: 'Card A', column: 1},
        {id: 2, title: 'Card B', column: 2},
        {id: 3, title: 'Card C', column: 2}
      ];

      this.cards$ = new Observable(observer =>
        this._cardsObserver = observer).share();
    }

    loadCards() {
      this._cardsObserver.next(this._dataStore);
    }

    addCard(){
      this._dataStore.push({id: 4, title: 'Card D', column: 3});
      this._cardsObserver.next(this._dataStore);
    }

    getColumns(){

      var columns = [
        {id: 1, title: 'Column One'},
        {id: 2, title: 'Column Two'},
        {id: 3, title: 'Column Three'}
      ];

      return columns;

    }

  }


  @Component({
    selector: 'app',
    providers: [DataService],
    directives: [],
    template: `
    <button (click)="dataService.addCard()">Add Card</button>
    <div class="columns" *ngFor="#c of columns">
      {{c.title}}
      <div class="card" *ngFor="#card of cards">{{card.title}}</div>
    </div>
    `
  })
  export class App {

    private cards: Array<Card>;
    private columns: any;

    constructor(public dataService: DataService) {
      dataService.cards$.subscribe(updatedCards => this.cards = updatedCards);
      dataService.loadCards();
      this.columns = dataService.getColumns();

    }
  }

【问题讨论】:

  • product.column?你是说卡吗?这是你想要的? :angular.io/docs/js/latest/api/common/NgIf-directive.html
  • 没错,card.column。
  • 无需过多修改您的示例,您可以添加类似 *ngIf="card.colum == column.id" 的内容或使用管道在 ngFor angular.io/docs/ts/latest/api/common/SlicePipe-class.html 中过滤它们,但您可能需要重新格式化您的数据结构以在更多高效的方式,因此您不必为每列迭代所有这些
  • 你可以在 Observable 上使用 .filter(card =&gt; card.id === card.column),在 .share() 之前的服务中或在 .subscribe() 之前的组件中
  • 不要将卡片保留在您的服务中,要么返回它们,要么返回它们的可观察对象或承诺,并将它们设置为控制器中的属性。您的逻辑现在太复杂了,难以理解、排除故障和维护,如果您像这样更改它并使用您的示例上传 repo 或 codepen/plunkr,我相信您会更快地获得帮助。

标签: angular


【解决方案1】:

就像@Langley 在他的评论中所说,我会为此创建一个自定义管道:

import {Injectable, Pipe} from 'angular2/core';

@Pipe({
  name: 'filter'
})
@Injectable()
export class CardFilterPipe implements PipeTransform {
  transform(items: any[], args: any[]): any {
    return items.filter(item => item.column === args[0]);
  }
}

然后像这样使用它:

<div class="columns" *ngFor="#c of columns">
  {{c.title}}
  <div class="card" *ngFor="#card of cards | filter:c">{{card.title}}</div>
</div>

如果要考虑更新,需要将pure属性设置为false:

@Pipe({
  name: 'filter',
  pure: false
})
@Injectable()
export class CardFilterPipe implements PipeTransform {
  (...)
}

希望对你有帮助 蒂埃里

【讨论】:

  • 您好 Thierry,此解决方案产生错误:EXCEPTION: Expression 'cards | App@4:29' 中的 filter:c 在检查后发生了变化。以前的值:''。当前值:'' in [cards | filter:c 在 App@4:29]
  • 我认为你需要启用生产模式才能没有这个消息。只需在引导您的应用程序之前添加此行:import {enableProdMode} from 'angular2/core'; enableProdMode();。有关生产模式的详细信息,请参阅此答案:stackoverflow.com/questions/34868810/…。希望对你有帮助。
  • @ThierryTemplier,由于在开发模式下存在状态管道的这个“问题”,因此有(更好的)替代方案可以使用生产模式:请参阅stackoverflow.com/a/34497504/215945。在生产模式下,我们失去了在开发模式下获得的宝贵的第二个变更检测周期,这可能会揭示我们的代码问题。 (但是在这种情况下,抛出的错误相当虚假/误导,如该链接中所述。)
  • 是的,你是对的,马克!总是很棒的 cmets ;-) 非常感谢您指出这一点并提供链接!后者我非常有用。
猜你喜欢
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 2015-12-17
  • 1970-01-01
相关资源
最近更新 更多