Html @viewChild和@ViewChildern给出了未定义的

Html @viewChild和@ViewChildern给出了未定义的,html,angular,typescript,Html,Angular,Typescript,我正在处理Angular 9,希望在单击按钮后访问输入字段。现在它给了我未定义的。我尝试了@ViewChild和@viewChildern,因为我正在使用ngIf Template.html文件 <div class="search-input" #searchDiv *ngIf="serachActive"> <input #searched autofocus type="text&q

我正在处理Angular 9,希望在单击按钮后访问输入字段。现在它给了我未定义的。我尝试了
@ViewChild
@viewChildern
,因为我正在使用
ngIf

Template.html文件

  <div class="search-input" #searchDiv *ngIf="serachActive">
    <input
    #searched
    autofocus
      type="text"
      class="serach-term"
      placeholder="Search"
      [(ngModel)]="searchTerms"
      (ngModelChange)="applySearch()"
    />
    <button (click)="toggleSearch(!serachActive)">
      <span class="material-icons"> search </span>
    </button>
  
    <ul class="search-list">
      <li *ngFor="let result of results">
        <a [routerLink]="['/', 'video', 'details', result._id]">{{
          result.title ? result.title : ''
        }}</a>
      </li>
    </ul>
  </div>
import { Component, OnInit,AfterViewInit,ElementRef,ViewChild,ViewChildren } from '@angular/core';
import { UserService } from '../../../user.service';
import { VideoService } from '../../../services/video.service';
import { Subject } from 'rxjs';
import { distinctUntilChanged, debounceTime } from 'rxjs/operators';
import { Router } from '@angular/router';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css'],
})
export class HeaderComponent implements OnInit,AfterViewInit{


  serachActive: boolean = false;
  @ViewChildren('searched') searchElement: ElementRef;
  @ViewChildren("searched") input: ElementRef;
  user;
  subject = new Subject<string>();
  results = [];
  searchTerms;
  loggedIn: Boolean = false;
  constructor(
    private userService: UserService,
    private videoService: VideoService,
    private router: Router
  ) {
    this.user = this.userService.getUser();
    this.loggedIn = this.userService.isAuthenticated();
  }
 



  ngOnInit() {
    console.log('on init', this.input);  //undefined
    this.subject
      .pipe(debounceTime(400), distinctUntilChanged())
      .subscribe((value) => {
        this.router.navigate(['search'], { queryParams: { term: value } });
      });
  }
  ngAfterViewInit() {
    console.log('on after', this.input);  //undefined
    
}

  toggleSearch(toggledata) {
    this.serachActive = toggledata;
    this.results = [];
    this.searchTerms = '';
    console.log(this.input)   //undefined
    console.log(this.searchElement.nativeElement) //undefined
   
  }
 
  applySearch() {
    const searchText = this.searchTerms;
    this.subject.next(searchText);
     this.searchElement.nativeElement.focus();  //undefined
 
  }

  menuButtonClick(button){
    if(button === "history"){
      this.router.navigate(['history'])
    }
  }
}

搜寻
    {{ result.title?result.title:' }}
Template.ts文件

  <div class="search-input" #searchDiv *ngIf="serachActive">
    <input
    #searched
    autofocus
      type="text"
      class="serach-term"
      placeholder="Search"
      [(ngModel)]="searchTerms"
      (ngModelChange)="applySearch()"
    />
    <button (click)="toggleSearch(!serachActive)">
      <span class="material-icons"> search </span>
    </button>
  
    <ul class="search-list">
      <li *ngFor="let result of results">
        <a [routerLink]="['/', 'video', 'details', result._id]">{{
          result.title ? result.title : ''
        }}</a>
      </li>
    </ul>
  </div>
import { Component, OnInit,AfterViewInit,ElementRef,ViewChild,ViewChildren } from '@angular/core';
import { UserService } from '../../../user.service';
import { VideoService } from '../../../services/video.service';
import { Subject } from 'rxjs';
import { distinctUntilChanged, debounceTime } from 'rxjs/operators';
import { Router } from '@angular/router';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css'],
})
export class HeaderComponent implements OnInit,AfterViewInit{


  serachActive: boolean = false;
  @ViewChildren('searched') searchElement: ElementRef;
  @ViewChildren("searched") input: ElementRef;
  user;
  subject = new Subject<string>();
  results = [];
  searchTerms;
  loggedIn: Boolean = false;
  constructor(
    private userService: UserService,
    private videoService: VideoService,
    private router: Router
  ) {
    this.user = this.userService.getUser();
    this.loggedIn = this.userService.isAuthenticated();
  }
 



  ngOnInit() {
    console.log('on init', this.input);  //undefined
    this.subject
      .pipe(debounceTime(400), distinctUntilChanged())
      .subscribe((value) => {
        this.router.navigate(['search'], { queryParams: { term: value } });
      });
  }
  ngAfterViewInit() {
    console.log('on after', this.input);  //undefined
    
}

  toggleSearch(toggledata) {
    this.serachActive = toggledata;
    this.results = [];
    this.searchTerms = '';
    console.log(this.input)   //undefined
    console.log(this.searchElement.nativeElement) //undefined
   
  }
 
  applySearch() {
    const searchText = this.searchTerms;
    this.subject.next(searchText);
     this.searchElement.nativeElement.focus();  //undefined
 
  }

  menuButtonClick(button){
    if(button === "history"){
      this.router.navigate(['history'])
    }
  }
}
从'@angular/core'导入{Component,OnInit,AfterViewInit,ElementRef,ViewChild,ViewChildren};
从“../../../user.service”导入{UserService};
从“../../../services/video.service”导入{VideoService};
从'rxjs'导入{Subject};
从'rxjs/operators'导入{distinctUntilChanged,debounceTime};
从'@angular/Router'导入{Router};
@组成部分({
选择器:“应用程序标题”,
templateUrl:'./header.component.html',
样式URL:['./header.component.css'],
})
导出类HeaderComponent实现OnInit,AfterViewInit{
serachActive:boolean=false;
@ViewChildren('searched')searchElement:ElementRef;
@ViewChildren(“搜索”)输入:ElementRef;
用户;
主题=新主题();
结果=[];
搜索词;
loggedIn:Boolean=false;
建造师(
私有用户服务:用户服务,
私人视频服务:视频服务,
专用路由器
) {
this.user=this.userService.getUser();
this.loggedIn=this.userService.isAuthenticated();
}
恩戈尼尼特(){
console.log('on init',this.input);//未定义
这个主题
.pipe(去BounceTime(400),distinctUntilChanged())
.订阅((值)=>{
这个.router.navigate(['search'],{queryParams:{term:value}});
});
}
ngAfterViewInit(){
console.log('on after',this.input);//未定义
}
切换搜索(切换数据){
this.serachActive=切换数据;
这个结果=[];
此.searchTerms='';
console.log(this.input)//未定义
console.log(this.searchElement.nativeElement)//未定义
}
applySearch(){
const searchText=this.searchTerms;
this.subject.next(searchText);
this.searchElement.nativeElement.focus();//未定义
}
菜单按钮单击(按钮){
如果(按钮==“历史”){
this.router.navigate(['history'])
}
}
}

使用
ViewChild
,因为您只搜索1个元素ID

如果在
ViewChild
中添加
{static:true}
{static:false}
选项不符合

改用
ChangeDetectorRef

@Component({...})
export class AppComponent {

  @ViewChild('searchInput') input: ElementRef;

  isShow: boolean = false;

  constructor(private cdr: ChangeDetectorRef) {}

  toggle(): void {
    this.isShow = !this.isShow;
    this.cdr.detectChanges();            // Detects changes which this.isShow is responsible on showing / hiding 
                                         // the element you're referencing to in ViewChild

    if (this.isShow)                     // If element is shown, console the referenced element 
      console.log(this.input);
  }

}

已经创建了一个供您参考的使用
ViewChild
,因为您只搜索一个元素ID

如果在
ViewChild
中添加
{static:true}
{static:false}
选项不符合

改用
ChangeDetectorRef

@Component({...})
export class AppComponent {

  @ViewChild('searchInput') input: ElementRef;

  isShow: boolean = false;

  constructor(private cdr: ChangeDetectorRef) {}

  toggle(): void {
    this.isShow = !this.isShow;
    this.cdr.detectChanges();            // Detects changes which this.isShow is responsible on showing / hiding 
                                         // the element you're referencing to in ViewChild

    if (this.isShow)                     // If element is shown, console the referenced element 
      console.log(this.input);
  }

}

已经创建了一个供您参考

这里有一个参考:-您可能希望尝试
@ViewChild()
{static:false}
(因为使用了
*ngIf
)@Neelavar我已经尝试过,但仍然得到
未定义的
。这里有一个参考:-您可能希望尝试
@ViewChild()
{static:false}
(因为使用了
*ngIf
)@Neelavar我已经试过了,但是仍然得到
未定义的
。谢谢,它在工作。@akshayTiwari,问题总是一样的,Angular会生成代码的所有指令并“刷新”应用程序。因此,如果您生成
这个。isShow=true;console.log(this.input)
此输入不存在。如果您编写
this.isShow=true;this.cdr.detetChanges();console.log(this.input)
此输入的存在是因为“cdr.detectchanges”使应用程序刷新。另一个选项是使用
this.isShow=true;setTimeout(()=>{console.log(this.input)}
因为setTimeout下的指令是在Angular刷新应用程序后执行的。谢谢,@Eliseo的这个解释实际上我在试图理解
ChangeDetectorRef
是如何解决我的问题的。但是这个解释帮了我很多。谢谢,它起作用了。@akshayTiwari,问题总是一样的,Angular使所有的指令解释代码并“刷新”应用程序。因此,如果您使
this.isShow=true;console.log(this.input)
此输入不存在。如果您编写
this.isShow=true;this.cdr.detetChanges();console.log(this.input)
此输入存在,因为“cdr.detectchanges”使应用程序刷新。另一个选项是使用
this.isShow=true;setTimeout(()=>{console.log(this.input)}
因为setTimeout下的指令是在应用程序刷新后执行的。谢谢@Eliseo的解释。实际上,我正在试图理解
ChangeDetectorRef
是如何解决我的问题的。但是这个解释对我帮助很大。