我正在为搜索创建一个自动完成控件,在这个过程中,我可以查找产品,一旦有人单击其中一个产品,他们应该导航到一个产品页面,该产品id位于URL中。
我目前的尝试使用了一个角材料自动完成(v7.3.7),并且我已经建模了这个例子(https://itnext.io/using-angular-6-material-auto-complete-with-async-data-6d89501c4b79)。
当搜索部分正常工作并选择一个产品时,当我试图从回调方法路由时,我会得到一个错误。我怀疑问题是,对于自动完成的路由器对象是不可见的,可能是因为它在FormGroup中。
一些注意事项:
首先,虽然我希望最终将其路由到产品页面,但我已经将路径简化为只是路由到主页。
我已经将路由器注入构造函数,并通过一个单独的测试按钮尝试了它,它工作得很好。我在FormGroup内外都尝试了测试按钮。
我还尝试将路由对象公开。
工作代码与教程示例非常接近,但我将在这里展示我所能做到的:
HTML
<form [formGroup]='prodForm'>
<mat-form-field class="example-full-width">
<input matInput [matAutocomplete]="auto" formControlName='prodInput'>
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="navToProd">
<mat-option *ngIf="isLoading" class="is-loading"><mat-spinner diameter="25"></mat-spinner></mat-option>
<ng-container *ngIf="!isLoading">
<mat-option *ngFor="let prod of filteredProds" [value]="prod">
<img class="example-option-img" [src]="prod.productImage.imagePath" height="35">
<span>{{ prod.productName }}</span>
<small> | {{prod.brand.brandName}} | {{prod.category.categoryName}}</small>
</mat-option>
</ng-container>
</mat-autocomplete>
<div>selected product: {{prodForm.get('prodInput').value | json}}</div>
<!-- just a test button to see if routing is working outside the control -->
<button class="btn" (click)="test()">TEST</button>
</form>和ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { FormBuilder, FormGroup } from '@angular/forms';
import { switchMap, debounceTime, tap, finalize } from 'rxjs/operators';
import { CatalogService } from '../shared-services/catalog.service';
import { SrfProduct } from '../data-objects/srf-obj-product';
@Component({
selector: 'app-test-alpha',
templateUrl: './test-alpha.component.html',
styleUrls: [
'../app.component.scss',
'./test-alpha.component.scss'
]
})
export class TestAlphaComponent implements OnInit {
filteredProds: SrfProduct[] = [];
prodForm: FormGroup;
isLoading = false;
constructor(
private router: Router,
private fb: FormBuilder,
private catalogService: CatalogService) { }
ngOnInit() {
this.prodForm = this.fb.group({
prodInput: null
})
// ===== GET by search term
this.prodForm.get('prodInput').valueChanges
.pipe(
debounceTime(300),
tap(() => this.isLoading = true),
switchMap(value => this.catalogService.getProductsBySearchTerm(value, 0, 10)
.pipe(
finalize(() => this.isLoading = false),
)
)
)
.subscribe(prods => this.filteredProds = prods);
}
navToProd(prod: SrfProduct) {
if (prod) {
this.router.navigate(['/home']); // <- this throws the error
return prod.productName;
}
}
test() {
this.router.navigate(['/home']); // <- but this works ok
}
}在所有情况下,当我从[displayWith]="navToProd"函数进行路由时,都无法读取未定义的错误的属性导航。
发布于 2019-07-08 18:43:32
您获得未定义错误的原因是由于这个上下文。当您将navToProd绑定为像[displayWith]="navToProd" 这样的输入时,这个上下文就会丢失,并且会产生未定义的错误。阅读一下javascript中的这个上下文
事件,尽管您修复了未定义的错误,但仍然以完全错误的方式使用[displayWith]="navToProd"。displayWith用于将选项控件值映射到显示值(如解释的在医生里 ),这意味着它计算(基于选项值)并返回一个字符串作为显示文本。这与选择无关。
如果要在用户选择选项时采取某些操作,则应使用optionSelected事件of MatAutoComplete
按以下方式更改html代码
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="navToProd($event)">并按以下方式修改navToProd方法
navToProd(event: MatAutocompleteSelectedEvent) {
const prod = event.option.value;
if (prod) {
this.router.navigate(['/home']); // change the url according to prod
}
}https://stackoverflow.com/questions/56940505
复制相似问题