简体   繁体   English

如何在过滤属性时将 ViewChildren QueryList 中的特定项目作为 ElementRef 获取?

[英]How to get specific item in ViewChildren QueryList as ElementRef while filtering on property(ies)?

I'm trying to set focus to any given input after that input changes (or potentially manipulate that same DOM element in other ways).我试图在输入更改后将焦点设置到任何给定输入(或可能以其他方式操作相同的 DOM 元素)。 I'm using Reactive Forms and the Form elements are rendered dynamically.我正在使用 Reactive Forms 并且表单元素是动态呈现的。

The problem I have is that I can access the element that has been changed using either @ViewChildren(AppTag) ipt:: QueryList<AppTag> which lets me filter on the element I want, but then I don't know how to grab that element using nativeElement , or I can use @ViewChildren(AppTag) ipt:: QueryList<ElementRef> , which (surprisingly) seems to be letting me filter the element in question, but (also surprisingly) I'm still unable to manipulate the DOM element.我遇到的问题是我可以使用@ViewChildren(AppTag) ipt:: QueryList<AppTag>访问已更改的元素,这让我可以过滤我想要的元素,但是我不知道如何抓住它元素使用nativeElement ,或者我可以使用@ViewChildren(AppTag) ipt:: QueryList<ElementRef> ,这(令人惊讶的)似乎让我过滤有问题的元素,但(同样令人惊讶的是)我仍然无法操作 DOM元素。 Either way, I get error: "itm.nativeElement is undefined" .无论哪种方式,我都会收到错误: "itm.nativeElement is undefined"

To reproduce the error, please enter any value into one of the Inputs in the following StackBlitz , and then TAB out of the entry.要重现错误,请在以下StackBlitz中的Inputs之一中输入任何值,然后在条目中使用TAB键。 You'll see the error in the console.您将在控制台中看到错误。

Below are what I think are the relevant pieces of code, but please play around with the full StackBlitz example to see the template and data structure more clearly:以下是我认为相关的代码片段,但请使用完整的 StackBlitz 示例以更清楚地查看模板和数据结构:

app.component.ts

export class AppComponent implements OnInit {
  @ViewChildren(AppTag) ipt !: QueryList<ElementRef>
  name = 'Angular';
  formCtls: any = {};
  form: FormGroup = new FormGroup({});
  data: {} = { // raw data
    name: 
    {
      first: {values: [""], label: "first name"},
      middle: {values: [""], label: "middle name"},
      last: {values: [""], label: "last name"}
    } 
  };
  dispData: any[] = []; // Data formatted for display/iteration by template
  itmNo: number = 0; // Unique ID for each Input
  focusItm = 0; // The bridge by which "FormControl.valueChanges" communicates with "QueryList.changes"

. . . 
. . .

  ngAfterViewInit() {
    this.ipt.changes.subscribe(list=>{
      setTimeout(()=>
        list.filter(itm=>+itm.id===this.focusItm).forEach(itm=>{
          console.log(`Item: ${itm.id} Focus: ${this.focusItm} ${+itm.id===this.focusItm}`);
          itm.nativeElement.focus();  // <-- HERE'S WHERE I'M HAVING THE TROUBLE
        }  
    ),0)}
    )
  }

. . . 
. . .


  renderDisplayArray(){
    this.dispData = [];
    this.itmNo = 0;

. . . 
. . .

          const i=r;
          this.formCtls[ctlName] = new FormControl(itm["values"][r], {updateOn: 'blur'});
          this.form.addControl(ctlName,this.formCtls[ctlName]);
          const curItm=this.itmNo;

          this.formCtls[ctlName].valueChanges.subscribe(val=>{
            console.log(`VALUE: ${val}`);
            itm["values"][i]=val || '';
            this.renderDisplayArray();
            this.focusItm = curItm;

          })
. . . 
. . .

Here's the Directive AppTag which I apply to the Inputs to be able to filter and grab the DOM elements I want.这是我应用于 Inputs 的 Directive AppTag ,以便能够filter和抓取我想要的 DOM 元素。 appTag.ts appTag.ts

import { Component, Directive, ElementRef, OnInit, Input } from "@angular/core";

@Directive({
  selector: '[appTag]'
})

export class AppTag implements OnInit{

constructor(private el: ElementRef) {}
@Input('appTag') id: number;

}

Just change the visibility from el: ElementRef in AppTag to public只需将 AppTag 中的el: ElementRef AppTag可见性更改为 public

@Directive({
  selector: '[appTag]'
})
export class AppTag implements OnInit{
   constructor(public el: ElementRef) {}
   @Input('appTag') id: number;
}

and use in your filter function the el property of the AppTag .并在您的过滤器 function 中使用AppTagel属性。

Change your problem line to this:将您的问题行更改为:

itm.el.nativeElement.focus();  // <-- HERE'S WHERE I'M HAVING THE TROUBLE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM