#javascript #angular #focus
Вопрос:
Эй, я не могу перенастроить недавно созданный элемент управления формой с помощью 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>
Комментарии:
1. Я знаю, что вы не хотите этого делать, но на самом деле проще всего сделать это rxjs debouncetimer
Ответ №1:
Вы можете использовать ссылку на шаблон и просмотреть детей,
<!--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"..>
Представление, которое используют {read:ElementRef}
дети, потому что вам нужен «html-тег», а не элемент управления формой
@ViewChildren('input',{read:ElementRef}) inputs:QueryList<ElementRef>
Тогда у вас есть два варианта:
1.-когда вы добавляете новую группу форм в массив, сделайте вдох(*) в Угловой и сфокусируйте последний элемент списка запросов
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()
})
}
(*)вам нужно подождать, чтобы перерисовать формат изображения перед фокусировкой, поэтому вы используете setInterval с «0 миллисекундами».
2.- Подпишитесь на inputs.valueChange в ngAfterViewInit-Изменение значения при добавлении/удалении одного элемента «Списка запросов»
ngAfterViewInit()
{
this.inputs.changes.subscribe(res=>{
if (res.length)
res.last.nativeElement.focus()
})
}