我正在设置发票Angular页面,其中动态添加行,每行应具有自己的自动完成输入以及其他不同的输入。我如何在组件内部独立引用每个自动完成输入,以便可以在内部使用正确的我的displayWith函数?
我的问题类似于this,但我在那里找不到正确的答案:(
HTML
<tr *ngFor="let ligneFacture of facture.lignesFacture; let i =index;">
<td width="5%" align="center">
<button type="button" class="button btn-primary"
style="border-radius: 50px;" disabled><span>{{i+1}}</span>
</button>
</td>
<td width="25%">
<form>
<mat-form-field>
<input type="text" class="form-control" matInput
(ngModelChange)="watchChangesArticle($event)"
(focus)="cursorFocusArticle($event)"
[matAutocomplete]="autoArticle"
[ngModelOptions]="{standalone: true}"
[(ngModel)]="ligneFacture.articleId">
<mat-autocomplete #autoArticle="matAutocomplete"
[displayWith]="displayFnArticle.bind(this)"
[autoActiveFirstOption]="true">
<mat-option *ngFor="let article of articles;"
[value]="article.id">
{{article.libelle}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</form>
</td>
<td width="10%"><input type="text" class="form-control"
style="text-align: center"
[ngModelOptions]="{standalone: true}"
[(ngModel)]="ligneFacture.unite"/>
<td width="10%"><input type="number" class="form-control" #quantity
id="quantity{{i+1}}"
[ngModelOptions]="{standalone: true}"
[(ngModel)]="ligneFacture.quantite"/>
</td>
<td width="13%">
<div class="input-group">
<input type="number" class="form-control"
[ngModelOptions]="{standalone: true}"
[(ngModel)]="ligneFacture.tauxTva" readonly/>
<div class="input-group-append">
<span class="input-group-text">%</span>
</div>
</div>
</td>
<td width="15%"><input type="number" class="form-control"
[ngModelOptions]="{standalone: true}"
[(ngModel)]="ligneFacture.prixUnitaire" tabindex="-1"
[value]="updateChanges(ligneFacture)"
readonly/></td>
<td width="15%"><input type="number" class="form-control"
[ngModelOptions]="{standalone: true}"
[(ngModel)]="ligneFacture.prixTotal" tabindex="-1" readonly/>
</td>
<td>
<div>
<button type="button" class="btn btn-danger"
(click)="removeLine(ligneFacture)" tabindex="-1">
<span>[X]</span>
</button>
</div>
</td>
</tr>
<br>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td colspan="2" align="right">
<button type="button" class="btn btn-primary" (click)="addLine()">
<span>[+] Ajouter une ligne</span>
</button>
</td>
</tr>
TS:
export class FactureUpdateComponent implements OnInit {
@ViewChild('autoArticle') matAutocompleteArticle: MatAutocomplete;
//
//
displayFnArticle(item) {
const matOptions = this.matAutocompleteArticle.options.filter(x => x.value === item);
if (matOptions.length !== 0) {
setTimeout(() => {
const element = document.getElementById('quantity' + this.facture.lignesFacture.length);
element.focus();
}, 0);
return matOptions.map(x => x.viewValue)[0];
} else {
return this.facture.lignesFacture.filter(x => x.articleId === item).map(x => x.articleLibelle);
}
}
watchChangesArticle(event, ligneFacture: ILigneFacture) {
this.articleService.queryByKeyword(event, this.req).subscribe(
(res: HttpResponse<IArticle[]>) => {
ligneFacture.articles = res.body;
},
(res: HttpErrorResponse) => this.onError(res.message)
);
}
cursorFocusArticle(event, ligneFacture: ILigneFacture) {
if (event.target.value === '') {
this.articleService.queryByKeyword('', this.req).subscribe(
(res: HttpResponse<IArticle[]>) => {
ligneFacture.articles = res.body;
},
(res: HttpErrorResponse) => this.onError(res.message)
);
}
}
}
预期结果:在displayFnArticle函数内部,我可以访问当前行的自动完成输入
Actual result:我只是可以访问相同的第一个自动完成输入ID,这可能会导致following dysfunction
答案 0 :(得分:1)
您可以在此处使用模板引用。文件:https://angular.io/guide/template-syntax#template-reference-variables--var-。
示例在这里:https://stackblitz.com/edit/angular-template-ref-with-fn
所以您有这样的HTML:
<button *ngFor="let i of array" #ref (click)="doStuff(ref)" class="{{ 'a' + i }}">{{ 'a' + i }}</button>
您可以这样处理:
doStuff(instance: HTMLElement) {
console.log('>> stuff', instance.classList);
}
这只是具有简单元素的示例,但是您可以使用MatAutocomplete进行同样的操作。
答案 1 :(得分:0)
在有关模板引用变量的注释中,我找到了一个在此处找到帮助的解决方案:
现在,我可以直接在自己的组件中访问当前的自动完成功能,而不再需要@ViewChild
HTML:
<mat-autocomplete #autoArticle="matAutocomplete" #currentAutocomplete
[displayWith]="displayFnArticle.bind(this, currentAutocomplete)" [autoActiveFirstOption]="true">
<mat-option *ngFor="let article of articles;"
[value]="article.id">
{{article.libelle}}
</mat-option>
</mat-autocomplete>
TS:
displayFnArticle(autocomplete: MatAutocomplete, item) {
const matOptions = autocomplete.options.filter(x => x.value === item);
if (matOptions.length !== 0) {
setTimeout(() => {
const element = document.getElementById('quantity' + this.facture.lignesFacture.length);
element.focus();
}, 0);
return matOptions.map(x => x.viewValue)[0];
} else {
return this.facture.lignesFacture.filter(x => x.articleId === item).map(x => x.articleLibelle);
}
}