【问题标题】:Template does not render observable using async pipe模板不使用异步管道呈现 observable
【发布时间】:2019-08-02 07:24:46
【问题描述】:

我只是从角度开始,在尝试了解自己发生了什么之后,我就是想不出一个解决方案。我有一个简单的模板:

<div *ngIf="allProducts$ | async as products">
  <div *ngIf="products.size > 0; else noProducts">
    <ul>
      <li *ngFor="let product of products" >
        <span>{{product.id}}</span>
        <span>{{product.name}}</span>
        <span (click)="productDetail(product)">Go to detail</span>
      </li>
    </ul>
  </div>
  <ng-template #noProducts>There are no products yet.</ng-template>
</div>

有一个类:

import {Component, OnInit} from '@angular/core';
import {Observable} from 'rxjs';
import {Product} from '../../model/product';
import {Router} from '@angular/router';
import {ProductService} from '../../service/product.service';

@Component({
  selector: 'app-product-list',
  templateUrl: './product-list.component.html',
  styleUrls: ['./product-list.component.css']
})
export class ProductListComponent implements OnInit {

  public allProducts$: Observable<Product[]>;

  constructor(private router: Router,
              private productService: ProductService) {}

  ngOnInit() {
    console.log('constructing ProductListComponent');
    this.allProducts$ = this.productService.getAllProducts();
  }

  productDetail(product: Product) {
    this.router.navigate([`product/${product.id}`]);
  }

}

最后,服务:

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {API_URL} from '../../app.constants';
import {Product} from '../model/product';
import {first, map} from 'rxjs/operators';
import {BehaviorSubject, Observable} from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  constructor(private http: HttpClient) {
  }

  addProduct(product: Product) {
    return this.http.post<Product>(`${API_URL}/product`, product, {observe: 'response'});
  }

  getAllProducts(): Observable<Product[]> {
    return this.http.get<Product[]>(`${API_URL}/product`, {observe: 'response'})
      .pipe(map(response => response.body), first());
  }
}

很简单的东西。我只是无法让它渲染。所以我尝试在服务中创建一个行为主体并将其订阅到http observable,并将其返回给组件而不是原始的http observable,认为可能组件没有机会及时订阅,如本文所述SO。没有运气。

接下来,受this SO question 的启发,我尝试在订阅中手动调用 markForCheck,完全移除异步管道。再次,什么都没有。

我无法找到任何其他解决方案,但这两种是最常见的方法,而且它似乎在任何地方都有效,例如 herehere。为什么它对我不起作用?显然,有一些简单的事情让我无法理解。当我在订阅 lambda 中的控制台中记录响应正文时,我可以看到我期望从后端获得的产品实体,但 ngOnInit 中的异步管道或订阅都不起作用。我还看到了一种使用ngZone.run 的方法,但我觉得它可以完成与常规订阅和markForCheck 相同的事情。

【问题讨论】:

  • products.size 你的意思是 products.length ?
  • 您能否验证您的 HTTP 调用是否正在返回数据?有时我喜欢通过以下方式进行调试:
     {{allProducts$ | json | async }}
    " 只是为了确保我将数据发送到模板。此外,如果您不需要 HTTP 标头信息,则 HttpClient 现在默认返回 JSON 响应正文作为可观察对象。跨度>
  • @MilosKovacevic 确实如此。
  • @DerrickF 数据被正确接收,但感谢关于不必在 HTTP 请求中包含响应选项的提示。

标签: angular angular2-observables


【解决方案1】:

这看起来不对...

<div *ngIf="products.size > 0; else noProducts">

你的意思是:

<div *ngIf="products.length > 0; else noProducts">

【讨论】:

    猜你喜欢
    • 2018-06-26
    • 2016-06-01
    • 1970-01-01
    • 2020-11-13
    • 1970-01-01
    • 2017-02-12
    • 2019-07-17
    • 1970-01-01
    • 2019-12-27
    相关资源
    最近更新 更多