模板无法使用异步管道进行观察

时间:2019-03-11 21:58:19

标签: angular angular2-observables

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

<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可观察的对象,然后将其返回到组件而不是原始的http可观察的对象,以为组件可能没有及时订阅的机会,如本文所述SO。没运气。

接下来,受this SO question的启发,我尝试在订阅中手动调用markForCheck,完全删除了异步管道。再说一遍。

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

1 个答案:

答案 0 :(得分:3)

这看起来不正确...

public class CheckBoxAndRadioButtons {

    public static void main(String[] args) throws InterruptedException {
        System.setProperty("webdriver.chrome.driver" , "C:/Users/User/Desktop/Selenium Drivers/chromedriver.exe");
        WebDriver driver = new ChromeDriver();
        driver.get("http://jqueryui.com/checkboxradio/");
        driver.manage().window().maximize();

        driver.switchTo().frame(driver.findElement(By.xpath("//iframe[@class='demo-frame']")));
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        WebElement radiobox = driver.findElement(By.xpath("/html/body/div/fieldset[1]/label[1]/span[1]"));
        boolean isDisplayedstatus = radiobox.isDisplayed();
        System.out.println(isDisplayedstatus);
        boolean isEnabledstatus = radiobox.isEnabled();
        System.out.println(isEnabledstatus);
        boolean isSelectedstatus = radiobox.isSelected();
        System.out.println(isSelectedstatus);

        Thread.sleep(2000);
        List<WebElement> ele = driver.findElements(By.xpath("//input[@type ='radio']"));
        for(WebElement we:ele) {
            if(!we.isSelected()) {
                we.click();
            }
        }

    }
}

您的意思是:

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