如何正确使用 mat-autocomplete 和远程 graphQL 数据?
How to properly use mat-autocomplete with remote graphQL data?
我在这里使用 angular 6 和 angular material,我正在尝试构建一个使用 graphQL 和 Apollo 的搜索组件。
嗯,该组件可以正常工作,但我想解决以下问题:
- 我想添加 debounceTime,但找不到确切的添加位置。
- 我不希望在 graphQL 查询中搜索空值
- 我不对 mat-autocomplete 使用异步过滤器,因为我将结果放在数组中。这是正确的方法吗?
我的与 graphQL 服务器交互的产品服务:
import { Injectable } from '@angular/core';
import {Apollo} from 'apollo-angular';
import gql from 'graphql-tag';
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private apollo: Apollo) { }
searchForProduct(productName: string) {
return this.apollo.watchQuery<any>({
query: gql`{products_by_p_name_search(lang_id:1,query:"${productName}")
{category_id,price,category_name,id,name,desc,quantity,year_manufacture,image_file}}`
});
}
}
我的搜索组件 html 与 mat-autocomplete
组件:
<form class="example-form">
<mat-form-field class="example-full-width">
<input matInput placeholder="חפש מוצר" aria-label="חפש מוצר" [matAutocomplete]="auto" [formControl]="productCtrl">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let product of products" [value]="product.name">
<img class="example-option-img" aria-hidden src="../../assets/products/{{product.id}}/{{product.imgFile}}_t.jpg" height="25">
<span>{{product.name}}</span> |
<small>Population: {{product.population}}</small>
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
最后是我的搜索组件(Typescript 文件):
import { Component, OnInit } from '@angular/core';
import {FormControl} from '@angular/forms';
import {Product} from '../product';
import {ProductService} from '../product.service';
@Component({
selector: 'app-search-product',
templateUrl: './search-product.component.html',
styleUrls: ['./search-product.component.scss']
})
export class SearchProductComponent implements OnInit {
productCtrl = new FormControl();
products: Product[] = [];
constructor(private productService: ProductService) {
}
ngOnInit() {
this.productCtrl.valueChanges
.subscribe(v => {
this.productService.searchForProduct(v.toString()).valueChanges.subscribe(
({data}) => {
const productsResult: Product[] = [];
data.products_by_p_name_search.forEach((productObj) => {
const product = new Product();
product.id = productObj.id;
product.categoryName = productObj.category_name;
product.name = productObj.name;
product.desc = productObj.desc;
product.quantity = productObj.quantity;
product.yearManufacture = productObj.year_manufacture;
product.imgFile = productObj.image_file;
product.categoryId = productObj.category_id;
product.price = productObj.price;
productsResult.push(product);
});
this.products = productsResult;
});
});
}
}
据我所知,这些代码行可以工作,但它可能不是最优化的编写方式。因此,我们将不胜感激有关上述问题的任何信息。
I want to add debounceTime and I can't find exactly where to add it.
您在订阅值更新的地方添加去抖动时间[]。您的 ngOnInit
看起来像这样
ngOnInit() {
this.productCtrl.valueChanges
.pipe(
debounceTime(500),
distinctUntilChanged()
)
.subscribe(v => {
...
别忘了import {debounceTime} from 'rxjs/operators';
。
I want that empty values won't be searched in the graphQL query
扔一个filter( value => value.length > 0)
您的 ngOnInit
现在类似于
ngOnInit() {
this.productCtrl.valueChanges
.pipe(
debounceTime(500),
distinctUntilChanged(),
filter( value => value.length > 0)
)
.subscribe(v => {
...
I don't use async filter for mat-autocomplete since I put the results inside an array. is that the correct way to go?
我不知道你不使用异步管道的原因。 有管道的工作演示。
我在这里使用 angular 6 和 angular material,我正在尝试构建一个使用 graphQL 和 Apollo 的搜索组件。
嗯,该组件可以正常工作,但我想解决以下问题:
- 我想添加 debounceTime,但找不到确切的添加位置。
- 我不希望在 graphQL 查询中搜索空值
- 我不对 mat-autocomplete 使用异步过滤器,因为我将结果放在数组中。这是正确的方法吗?
我的与 graphQL 服务器交互的产品服务:
import { Injectable } from '@angular/core';
import {Apollo} from 'apollo-angular';
import gql from 'graphql-tag';
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private apollo: Apollo) { }
searchForProduct(productName: string) {
return this.apollo.watchQuery<any>({
query: gql`{products_by_p_name_search(lang_id:1,query:"${productName}")
{category_id,price,category_name,id,name,desc,quantity,year_manufacture,image_file}}`
});
}
}
我的搜索组件 html 与 mat-autocomplete
组件:
<form class="example-form">
<mat-form-field class="example-full-width">
<input matInput placeholder="חפש מוצר" aria-label="חפש מוצר" [matAutocomplete]="auto" [formControl]="productCtrl">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let product of products" [value]="product.name">
<img class="example-option-img" aria-hidden src="../../assets/products/{{product.id}}/{{product.imgFile}}_t.jpg" height="25">
<span>{{product.name}}</span> |
<small>Population: {{product.population}}</small>
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
最后是我的搜索组件(Typescript 文件):
import { Component, OnInit } from '@angular/core';
import {FormControl} from '@angular/forms';
import {Product} from '../product';
import {ProductService} from '../product.service';
@Component({
selector: 'app-search-product',
templateUrl: './search-product.component.html',
styleUrls: ['./search-product.component.scss']
})
export class SearchProductComponent implements OnInit {
productCtrl = new FormControl();
products: Product[] = [];
constructor(private productService: ProductService) {
}
ngOnInit() {
this.productCtrl.valueChanges
.subscribe(v => {
this.productService.searchForProduct(v.toString()).valueChanges.subscribe(
({data}) => {
const productsResult: Product[] = [];
data.products_by_p_name_search.forEach((productObj) => {
const product = new Product();
product.id = productObj.id;
product.categoryName = productObj.category_name;
product.name = productObj.name;
product.desc = productObj.desc;
product.quantity = productObj.quantity;
product.yearManufacture = productObj.year_manufacture;
product.imgFile = productObj.image_file;
product.categoryId = productObj.category_id;
product.price = productObj.price;
productsResult.push(product);
});
this.products = productsResult;
});
});
}
}
据我所知,这些代码行可以工作,但它可能不是最优化的编写方式。因此,我们将不胜感激有关上述问题的任何信息。
I want to add debounceTime and I can't find exactly where to add it.
您在订阅值更新的地方添加去抖动时间[ngOnInit
看起来像这样
ngOnInit() {
this.productCtrl.valueChanges
.pipe(
debounceTime(500),
distinctUntilChanged()
)
.subscribe(v => {
...
别忘了import {debounceTime} from 'rxjs/operators';
。
I want that empty values won't be searched in the graphQL query
扔一个filter( value => value.length > 0)
您的 ngOnInit
现在类似于
ngOnInit() {
this.productCtrl.valueChanges
.pipe(
debounceTime(500),
distinctUntilChanged(),
filter( value => value.length > 0)
)
.subscribe(v => {
...
I don't use async filter for mat-autocomplete since I put the results inside an array. is that the correct way to go?
我不知道你不使用异步管道的原因。