在angular中添加formControl后,我如何在没有settimeout的情况下将焦点更改为新的formCont



嘿,我不能引用新创建的formControl与dom,因为它是滞后一行每次,这是由于同步和异步行为造成的,但无法找出如何克服这种滞后。

我已经尝试了所有的生命周期循环,但没有成功。因为我必须改变输入的动态行上的焦点,我必须在创建输入行的同时实现这一点,但它是在视觉上创建的,但在保存的变量实例中,它滞后了。这可能是由于异步函数和我保存的变量在更新之前被初始化。

这是我的代码块

onAddTaka() {
let takaNum: string = '';
let indx = (<FormArray>this.productionForm.get('takas')).length - 1;
if (indx >= 0) {
let formGrp = (<FormArray>this.productionForm.get('takas')).at(indx);
let lastTakaNumber = formGrp.value.takaNumber.split(this.serialPrefix)[1];
takaNum = this.serialPrefix + (parseInt(lastTakaNumber) + 1);
} else {
takaNum = this.serialPrefix + this.serialStart;
}
(<FormArray>this.productionForm.get('takas')).push(
new FormGroup({
'takaNumber': new FormControl(takaNum, Validators.required),
'weight': new FormControl(null, [Validators.required, Validators.min(0)]),
'length': new FormControl(null, [Validators.required, Validators.min(0)])
})
);
this.onTakaNumberChange({target : { value: takaNum}},indx + 1);
}
kd(ele, plc) {
if(ele.keyCode == 13) {
ele.preventDefault();
if(ele.ctrlKey == true) {
document.getElementById("save_btn").focus();
}
switch(plc){
case 0 : ele.path[2].children[1].children[0].focus();
break;
case 1 : ele.path[2].children[2].children[0].focus();
break;
case 2 :
this.onAddTaka();
setTimeout(() => {
this.updateEle();
this.setFocus();
}, 1);
break;
default:
this.alertMessage = "Some thing went Wrong in key Press detection Contact support!";
}

}
}

updateEle(){
this.le = <HTMLElement>document.body.children[0].children[2].children[0].children[1].children[1].children[1].lastElementChild;
if(this.le) {
this.le = (<HTMLElement>this.le.children[0].children[0]);
}
}
setFocus() {
this.le.focus();
}
onTakaNumberChange(event: any, index: number) {
let inputTakaNumber = event.target.value;

this.takaNumberVerified = this.takaService.isUniqueTakaNumber(inputTakaNumber);
if (!this.takaNumberVerified) {
this.alertMessage = `The Taka Number (${inputTakaNumber}) is already used Try another One in row ${index + 1}`;
}
let str;
if (this.takaNumberVerified) {
str = 'form-control is-valid';
} else {
str = 'form-control is-invalid';
}
this.avgWt.forEach((item, i) => {
if (index === i) {
item.nativeElement.children[0].children[0].className = str;
}
});
}
get controls() {
return (<FormArray>this.productionForm.get('takas')).controls;
}

这是html

<section class="container" *ngIf="voucherGenerated">
<br>
<table class="table table-striped table-hover text-center">
<thead>
<tr>
<th scope="col">Taka No.</th>
<th scope="col">Length (in mtr.)</th>
<th scope="col">Weight</th>
<th scope="col">Avg. Weight</th>
</tr>
</thead>
<tbody formArrayName="takas">
<tr *ngFor="let takaCtrl of controls; let i = index;" [formGroupName]="i" #avgWt>
<th scope="row">
<input type="text" name="takaNumber" id="takaNumber" class="form-control" placeholder="W00001" formControlName="takaNumber" (keydown)="kd($event,0)" (focusout)="onTakaNumberChange($event,i)">
</th>
<td>
<input type="number" name="length" id="takaLength" class="form-control" placeholder="Length" formControlName="length" (keydown)="kd($event,1)" (input)="onChange($event,1,i)">
</td>
<td>
<input type="number" name="Weight" id="takaWeight" class="form-control" placeholder="Weight" formControlName="weight" (keydown)="kd($event,2)" (input)="onChange($event,0,i)">
</td>
<td>
<span class="form-control">0</span>
</td>
<td>
<button type="button" class="btn btn-danger" (click)="onRemoveTaka(i)">X</button>
</td>
</tr>
</tbody>
</table>
<hr>
<div class="row mb-2 mt-2">
<div class="col">
<button type="button" class="btn btn-outline-dark" (click)="onAddTaka()">Add Taka</button>
</div>
<div class="col text-end">
<button id="save_btn" class="btn btn-primary" type="submit" [disabled]="!productionForm.valid">Save Production</button>
</div>
</div>
</section>

你可以使用模板引用和ViewChildren,

<!--use #input in the "input" you want to make the focus-->
<-- NOT in the others, e.g. you want to focus in "takaNumber"
<input #input type="text" name="takaNumber"..>

viewChildren使用{read:ElementRef},因为你想要"html标签",而不是formControl

@ViewChildren('input',{read:ElementRef}) inputs:QueryList<ElementRef>

那么你有两个选择:

1。-当你向数组中添加一个新的FormGroup时,给Angular一个喘息(*),并关注QueryList的最后一个元素

onAddTaka() {
....
setTimeout(()=>{
//if you want to focus the nth-index
//use inputs.find((_,i)=>i==index).nativeElement.focus()
//if you want the nth
inputs.last.nativeElement.focus()
})
}

(*)你需要等待重新绘制FormArray之前的焦点,所以你使用setInterval "0毫秒">

2。-订阅输入。当我们添加/删除"QueryList"中的一个元素时,valueChange会发生变化

ngAfterViewInit()
{
this.inputs.changes.subscribe(res=>{
if (res.length)
res.last.nativeElement.focus()
})
}

相关内容

最新更新