【问题标题】:Angular 2 Usage of Http Observable and PipeAngular 2 使用 Http Observable 和 Pipe
【发布时间】:2017-02-02 08:05:38
【问题描述】:

我有一个调用 REST 端点的服务:

import { Task } from './task';
import { TaskStatus } from './task-status';
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';

@Injectable()
export class TaskService {
    constructor(private http: Http){
    }
    getTasks() {
        return this.http.get('http://localhost:8080/tasks').map(res => res.json()).map(rest => rest._embedded.tasks);
    }
}

端点返回如下结果:

{
  "_embedded": {
    "tasks": [
      {
        "title": "zxc",
        "description": "zxc",
        "status": "New",
        "_links": {
          "self": {
            "href": "http://localhost:8080/tasks/1"
          },
          "task": {
            "href": "http://localhost:8080/tasks/1"
          }
        }
      },
      {
        "title": "asd",
        "description": "qweqwe",
        "status": "New",
        "_links": {
          "self": {
            "href": "http://localhost:8080/tasks/2"
          },
          "task": {
            "href": "http://localhost:8080/tasks/2"
          }
        }
      }
    ]
  },
  "_links": {
    "self": {
      "href": "http://localhost:8080/tasks"
    },
    "profile": {
      "href": "http://localhost:8080/profile/tasks"
    }
  },
  "page": {
    "size": 20,
    "totalElements": 3,
    "totalPages": 1,
    "number": 0
  }
}

我在这个组件中使用服务:

@Component({
  selector: 'app-mycomp',
  templateUrl: './my.component.html',
  styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {
  tasks: Array<Task>;

  constructor(private taskService:TaskService) {
    taskService.getTasks()
    .subscribe(tasks => this.tasks = tasks, 
                err => console.error(err), 
                () => console.log('done'));
  }
}

模板看起来像这样;

<task-details *ngFor="let task of tasks" [task]="task"></task-details>

这按预期工作,但是当我尝试在模板中使用管道时:

<task-details *ngFor="let task of tasks | WithStatus: TaskStatus.New" [task]="task"></task-details>

我收到错误“无法读取未定义的属性'过滤器'”。

这是管道实现:

import { Pipe, PipeTransform } from '@angular/core';
import { TaskStatus } from './task-status';

@Pipe({ name: 'WithStatus', pure: true })
export class TaskStatusFilter implements PipeTransform{
    transform(value: any, ...args: any[]): any {
        console.log(value);// value is undefined
        return value.filter(item => item.status == args[0]);
    }
}

【问题讨论】:

  • WithStatus: TaskStatus.New TaskStatus.New 是什么?你在任何地方都没有这样的东西......

标签: angular typescript angular2-http angular2-pipe


【解决方案1】:

在初始更改检测周期中,当 ajax 尚未完成时,它会尝试评估 bindings 并将 tasks 值(如 undefined 中的值)传递给 WithStatus 管道,并引发错误。对于这种情况,您只能在管道内处理它。

@Pipe({ name: 'WithStatus', pure: true })
export class TaskStatusFilter implements PipeTransform{
    transform(value: any, ...args: any[]): any {
        console.log(value);// value is undefined
        return (value || []).filter(item => item.status == args[0]);
    }
}

另一种方法是您应该在 DOM 树中注入 task-details DOM,直到使用 *ngIf 结构指令成功实现 ajax。

<template [ng-if]="tasks">
  <task-details 
    *ngFor="let task of tasks | WithStatus: TaskStatus.New" 
    [task]="task">
  </task-details>
</template>

您也可以使用&lt;ng-container&gt; 代替&lt;template&gt;,它允许使用与内联*ngIf 相同的语法:

<ng-container *ngIf="tasks">
  <task-details 
    *ngFor="let task of tasks | WithStatus: TaskStatus.New" 
    [task]="task">
  </task-details>
</ng-container>

【讨论】:

  • 谢谢@yurzui先生,我不知道ng-container,我没有找到任何提及相同的资源,请您提供参考,感谢您的帮助:)
  • 不幸的是,没有关于 ng-container 的好的文档。最好的参考是这个github.com/angular/angular/blob/2.1.0-beta.0/modules/%40angular/…
  • @yurzui 很酷,再次感谢您的帮助,您在 Angular 2 团队工作吗?
【解决方案2】:

您可以尝试*ngIf="task"。在数据到达之前,它不会初始化您的管道。

<div *ngIf="tasks" >
<task-details *ngFor="let task of tasks | WithStatus: TaskStatus.New" 
              [task]="task"></task-details>
</div>

【讨论】:

    猜你喜欢
    • 2016-10-06
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    • 2017-06-17
    • 1970-01-01
    • 2016-12-12
    • 1970-01-01
    • 2018-12-05
    相关资源
    最近更新 更多