【问题标题】:@ViewChild not working after upgrading to Angular 9@ViewChild 升级到 Angular 9 后无法正常工作
【发布时间】:2020-05-30 11:53:57
【问题描述】:

升级到 Angular 9 后,基本上我所有的 @ViewChild 引用都不再初始化了。

不管怎样,

<app-menu-editor #menuEditor>
</app-menu-editor>

<div #cardBody>
  <!-- ... -->
</div>
@ViewChild('menuEditor', {read: MenuEditorComponent}) menuEditor: MenuEditorComponent;

@ViewChild('cardBody', {read: ElementRef}) cardBody: ElementRef;

我不断收到异常告诉我,例如menuEditorundefined

知道为什么这不再起作用了吗?

【问题讨论】:

  • 很可能是因为您在 ngOnInit 而不是 ngAfterViewInit 中访问它们

标签: angular


【解决方案1】:

试试

@ViewChild('menuEditor', {static: true, read: MenuEditorComponent}) menuEditor: MenuEditorComponent;

@ViewChild('cardBody', {static: true, read: ElementRef}) cardBody: ElementRef;

就像 PierreDuc 所说,也许您在 ngOnInit 中指的是他们。

【讨论】:

  • 为什么他们一直在改变这个东西?每次升级时,我都必须以不同的方式执行此操作或更改某些内容以消除警告。但是,谢谢。这确实是问题所在。
  • 这是 v8 中的一个实验性更改,更倾向于让每个人都知道它的含义,并且明确提到 v9 不会有这些,所以如果你需要它 onInit,你将不得不@987654323 @
  • @displayname 如果你想升级你的 Angular 版本,你应该使用 cli。这将自动处理所有这些事情,或者给你一个警告说你应该检查这些地方。
  • 在我用最新版本更新 angular 并且已经使用 @ViewChild() 但 var 值未定义的前 2 天。例如。 @ViewChild(childComponent,{static: true})_childCmpt: childComponent;当我在按钮单击时打印 _childCmpt 然后变得未定义。我正在使用包 - “@angular/animations”:“~11.2.6”、“@angular/cdk”:“^11.2.7”、“@angular/common”:“~11.2.6”、“@angular /compiler": "~11.2.6", "@angular/core": "^11.2.8", "@angular/forms": "~11.2.6",
  • 另外,我同意 Stefan Falk 的观点,当我更新 Angular 版本时,某些功能无法正常工作。每次都需要修改一些东西。
【解决方案2】:

我猜你在 ngOnInit 钩子内或在类构造函数内得到 undefined。如果我的猜测是正确的,那么这就是你的问题:

视图子在ngOnInit 中变得可用如果您在@ViewChild 装饰器中使用static: true 选项。如果未设置 static: true 选项,则您的子视图仅在 ngAfterViewInit 中可用。 static 选项设置为 false by default

This SO answer 也可能有帮助。

【讨论】:

    【解决方案3】:

    我有另一个角度为 9 的场景,我花了两天时间才弄清楚。

    我的问题是没有一个解决方案有效;事实上,ViewChild 和 ViewChildren 都没有在 ANGULAR 9 中工作。

    经过大量调查且未发出警告后,问题是我的 @ViewChild 属于未标记为 @Component 的抽象类。

    所以,如果你正在做这样的事情:

    export abstract class AbstractBaseComponent {
       @ViewChild('test') public testRef: TestComponent;
    }
    
    @Component({
       'selector': 'base-component'
    })
    export class BaseComponent extends AbstractBaseComponent {
        ngAfterViewInit() {
            console.log(this.testRef);
        }
    }
    

    这行不通。 您还必须在抽象类上添加@Component

    @Component({})
    export abstract class AbstractBaseComponent {
       @ViewChild('test') public testRef: TestComponent;
    }
    

    可以(间接)在角度 9 的重大变化中找到有关此的进一步阅读:

    虽然没有提到抽象类遵循相同的行为,但实际上它是按原样设计的,因为抽象类在技术上没有被转译。

    【讨论】:

      【解决方案4】:

      对于 Angular 8 及更高版本,您可以选择以下方法:

       @ViewChild('txtName', {static: false}) txtName: ElementRef;
          
          { static: true } needs to be set when you want to access the ViewChild in ngOnInit.
              
          { static: false } can only be accessed in ngAfterViewInit. This is also what you want to go for when you have a structural directive (i.e. *ngIf) on your element in your template.
      

      【讨论】:

        猜你喜欢
        • 2019-10-30
        • 2019-10-03
        • 1970-01-01
        • 2015-11-03
        • 2020-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多