首页 > 解决方案 > 我们如何过滤可观察的项目?

问题描述

模型如下所示

export class FileQueueObject {
    public file: any; // used any because selected file contain.
    public status: FileQueueStatus = FileQueueStatus.Pending;
    public progress = 0;
    public request: Subscription = null;
    public response: HttpResponse<object> | HttpErrorResponse = null;

    constructor(file: any) {
        this.file = file;
    }

    // statuses
    public isPending = () => this.status === FileQueueStatus.Pending;
    public isSuccess = () => this.status === FileQueueStatus.Success;
    public isError = () => this.status === FileQueueStatus.Error;
    public inProgress = () => this.status === FileQueueStatus.Progress;
    public isUploadable = () => this.status === FileQueueStatus.Pending || this.status === FileQueueStatus.Error;
}

TS

queue: Observable<FileQueueObject[]>;

html 如下所示

3 问题:

我想要实现的是,

1 -inProgress === true放在不同部分的项目。

<span>Uploading <span>
        <ul>
        <li *ngFor="let item of queue | async"> 
            <div>{{ item.file?.name }}</div>
            <div>{{ item.file?.size }}</div>
            <a *ngIf="item.inProgress()">Cancel</a>
        </li>
        <ul>

2 -isSuccess===true放在不同部分的项目。

<span>Uploaded <span>
        <ul>
        <li *ngFor="let item of queue | async"> 
            <div>{{ item.file?.name }}</div>
            <div>{{ item.file?.size }}</div>
            <a *ngIf="!item.inProgress()">Remove</a>
        </li>
        <ul>

如果只有 1 个项目属于该类别,则标题应该可见。

3 - 是否可以通过只写 1 个 html 来实现,如下所示?

<span *ngIf="">Uploading <span>  
<span *ngIf="">Uploaded <span>
            <ul>
            <li *ngFor="let item of queue | async"> 
                <div>{{ item.file?.name }}</div>
                <div>{{ item.file?.size }}</div>
                <a *ngIf="item.inProgress()">Cancel</a>
                <a *ngIf="!item.inProgress()">Remove</a>
            </li>
            <ul>

你有什么建议,如果我想将项目显示为上传和上传,上传会有取消按钮,上传会有删除按钮

我尝试的是

    getInProgressItem(): any {
    // tslint:disable-next-line:only-arrow-functions
    // tslint:disable-next-line:typedef
    const a = this.queue.pipe(filter((result, id): any => {
      return result.filter((x) => x.inProgress() === true);
    }));
    return a;
  }

  getSuccussItem(): any {
    // tslint:disable-next-line:only-arrow-functions
    // tslint:disable-next-line:typedef
    // tslint:disable-next-line:no-unused
    const b = this.queue.pipe(filter((result, id): any => {
      return result.filter((x) => x.isSuccess() === true);
    }));
    return b;
  }
<span *ngIf="(getInProgressItem().length > 0 | async)"
          class="c-fileupload__indicator">Uploading</span>
    <span *ngIf="(getSuccussItem().length > 0 | async)"
          class="c-fileupload__indicator">Uploaded</span>

它不适合我

标签: javascriptangularrxjs

解决方案


我认为适当的解决方案是将您的可观察队列拆分为 2 个可观察对象,如下所示:

queueSuccessfulItems = this.queue.pipe(map(items => items.filter(item => item.isSuccess())))
queueInProgressItems = this.queue.pipe(map(items => items.filter(item => item.inProgress())))

然后像这样使用它

<ng-template #itemTemplate let-item="item">
   <div>{{ item.file?.name }}</div>
   <div>{{ item.file?.size }}</div
</ng-template>

<ng-container *ngIf="queueInProgressItems | async as inProgressItems">
  <div *ngIf="inProgressItems.length"> <!-- here we have an array, not a stream -->
   <span>Uploading <span>
    <ul>
     <li *ngFor="let item of inProgressItems"> 
       <ng-container 
        *ngTemplateOutlet="itemTemplate;context:{item: item}">
       </ng-container>
       <a>Cancel</a>
    </li>
   </ul>
 </div>

<ng-container *ngIf="queueSuccessfulItems | async as successfulItems">
  <div *ngIf="successfulItems.length">
   <span>Uploaded <span>
    <ul>
     <li *ngFor="let item of successfulItems"> 
       <ng-container 
        *ngTemplateOutlet="itemTemplate;context:{item: item}">
       </ng-container>
       <a>Remove</a>
    </li>
   </ul>
 </div>


推荐阅读