在更新 MatTableDataSource 后,焦点消失 Angular

huangapple go评论65阅读模式
英文:

After updating MatTableDataSource focus disappears angular

问题

在更新一行中的输入元素并点击下一行中的输入后,焦点消失,因为数据源得到更新。是否有方法在更新数据源的同时保持焦点?我花了很多时间在这上面。如果有人知道如何解决,请告诉我。谢谢。

focusedIn(event: Event, article: ArticleDef): void {
    this.activeArticle = article;
    this.facade.active(article.id);
    (event.target as HTMLInputElement).focus();
}
ngOnChanges(changes: SimpleChanges): void {
    if (changes.articles) {
    this.dataSource = new MatTableDataSource<ArticleDef & Selectable>(changes.articles.currentValue);
    }
}
changeQuantity(event: Event, article: ArticleDef): void {
    this.quantityChange.emit({
        id: article.id,
        name: article.name,
        quantity: parseInt((event.target as HTMLInputElement).value)
    });
}
英文:

After updating the input element in one row and clicking on the input in the next row, the focus disappears because the datasource gets updated. Is there any way to preserve focus while updating datasource? I have spent a lot of time on it. If someone knows how it can be solved let me know. Thanks.

focusedIn(event: Event, article: ArticleDef): void {
    this.activeArticle = article;
    this.facade.active(article.id);
    (event.target as HTMLInputElement).focus();
}
 ngOnChanges(changes: SimpleChanges): void {
    if (changes.articles) {
    this.dataSource = new MatTableDataSource<ArticleDef & Selectable>(changes.articles.currentValue);
    }
}

  changeQuantity(event: Event, article: ArticleDef): void {
    this.quantityChange.emit({
      id: article.id,
      name: article.name,
      quantity: parseInt((event.target as HTMLInputElement).value)
    });
  }

答案1

得分: 0

当您更改数据时,Angular会“重新绘制”表格。因此,在聚焦之前,您需要“等待”重新绘制。通常可以使用setTimeout(不带毫秒)或调用ChangeDetectorRef.detectChanges()。

我不确定是否适用于更改您的focusedIn函数:

focusedIn(event: Event, article: ArticleDef): void {
    this.activeArticle = article;
    this.facade.active(article.id);

    setTimeout(() => {
       (event.target as HTMLInputElement).focus();
    });
}

或者在更新表格数据源时更改,使用ViewChild(当您有多个具有相同模板引用变量的标签时,ViewChild会获取第一个):

ViewChild("InputFocus", { read: ElementRef }) input: ElementRef;

ngOnChanges(changes: SimpleChanges): void {
 if (changes.articles) {
    this.dataSource = new MatTableDataSource<ArticleDef & Selectable>(changes.articles.currentValue);

    // 在setTimeout内聚焦第一个
    setTimeout(() => {
       this.input.nativeElement.focus();
    });
 }
}
英文:

When you change the data, Angular "repaint" the table. So you need "wait" the repaint before focus. Generally you can use a setTimeout -without milisecons- or calling to ChangeDetectorRef.detectChanges()

Really I dont' know if works change your focusedIn function

focusedIn(event: Event, article: ArticleDef): void {
    this.activeArticle = article;
    this.facade.active(article.id);

    setTimeout(()=&gt;{
       (event.target as HTMLInputElement).focus();
    })
}

Or change when update the table dataSource using a ViewChild (a ViewChild when you have severals tags with the same template referenceVariable gets the first one

ViewChild(&quot;InputFocus&quot;,{read:ElementRef}) input:ElementRef

ngOnChanges(changes: SimpleChanges): void {
 if (changes.articles) {
    this.dataSource = new MatTableDataSource&lt;ArticleDef &amp; Selectable&gt;(changes.articles.currentValue);

    //inside a setTimeout focus the first
    setTimeout(()=&gt;{
       this.input.nativeElement.focus();
    })
 }

答案2

得分: 0

以下是翻译好的代码部分:

focusedIn(event: Event, article: ArticleDef): void {
    this.activeArticle = article;
    this.returnArticlesFacade.active(article.id);
    setTimeout(() => {
        (event.target as HTMLInputElement).focus();
    }, 0);
}

ngOnChanges(changes: SimpleChanges): void {
    if (changes.articles) {
        this.dataSource = new MatTableDataSource<ArticleDef & Selectable>(changes.articles.currentValue);

        // 这里根据您的需求更改条件
        if (this.activeArticle) {
            setTimeout(() => {
                // 我们假定 this.activeArticle.id 是元素的 id。如果不是,请根据您的需求进行更改
                const element = document.getElementById(this.activeArticle.id).getElementsByTagName('input')[0];
                element.focus();
            }, 0);
        }
    }
}

希望这对您有所帮助。

英文:

It can be done as follow:

focusedIn(event: Event, article: ArticleDef): void {
    this.activeArticle = article;
    this.returnArticlesFacade.active(article.id);
    setTimeout(() =&gt; {
      (event.target as HTMLInputElement).focus();
    }, 0);
 }
 
 ngOnChanges(changes: SimpleChanges): void {
 if (changes.articles) {
    this.dataSource = new MatTableDataSource&lt;ArticleDef &amp; Selectable&gt;(changes.articles.currentValue);

   // Here you can change if condition according to your requirement
   if (this.activeArticle) {
      setTimeout(() =&gt; {
        //WE are passing this.activeArticle.id by assuming that it is the id of the element. If it is not then change it according to your requirement
        const element = document.getElementById(this.activeArticle.id).getElementsByTagName(&#39;input&#39;)[0];
        element.focus();
      }, 0);
   }
 }

huangapple
  • 本文由 发表于 2023年7月18日 16:20:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76710797.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定