【问题标题】:Unable to get hold of child DOM element无法获取子 DOM 元素
【发布时间】:2017-06-01 09:38:53
【问题描述】:

注意:由于问题有点复杂,为了便于阅读,对代码进行了抽象

我们有一个这样的<parent-component>

<child-component></child-component>
<button (click)="doSomeClick()"> Do Some Click </button>

&lt;child-component&gt; 中的template 是:

<textarea #childComponentElement #someField="ngModel" name="someName" [(ngModel)]="someModel"></textarea>

我们正在尝试访问 parent-component.component.ts 中此元素的值,如下所示:

export class ParentComponent implements AfterViewInit {
    @ViewChild('childComponentElement') el:ElementRef;

    ngAfterViewInit() {
        console.log(this.el.nativeElement.value);
    }
    doSomeClick(){

    }
}

但是它会抛出这个错误:

无法读取未定义的属性“nativeElement”

到目前为止我们尝试了什么:

【问题讨论】:

  • 你试过这里的方法吗:angular.io/docs/ts/latest/guide/…
  • @Edwin ngAfterViewInit 在这种用法中是正确的。只是他试图从一个模板不属于的父组件访问templateRef。

标签: javascript html angular typescript


【解决方案1】:

使用嵌套组件没有简单的方法,您必须创建一个 EventEmitter 来发出您尝试访问的元素的 ElementRef

child.component.ts

class ChildComponent implements AfterViewInit {

    @Output()
    templateLoaded: EventEmitter<ElementRef> = new EventEmitter()

    @ViewChild('childComponentElement') el: ElementRef

    ngAfterViewInit(): void {
        this.templateLoaded.emit(this.el)
    }
}

parent.component.html

<child-component (templateLoaded)="templateLoaded($event)"

parent.component.ts

class ParentComponent {

    templateLoaded(template: ElementRef): void {
        // do stuff with the `template`
    }
}

原答案

尝试在ViewChild 的第二个参数中使用read 属性

@ViewChild('childComponentElement', {read: ElementRef}) el: ElementRef

如果您对第二个参数感到疑惑,这个答案给出了很好的解释:What is the read parameter in @ViewChild for

【讨论】:

  • 使用read属性后,this.el仍然未定义。
  • @xameeramir Ahh,您是否尝试从没有该 html 作为模板的父组件访问 ElementRef
  • 是的,我们正在从parent-component.component.ts 访问&lt;textarea&gt; of &lt;child-component&gt;
  • 如何在ParentComponent内部触发templateLoaded进行验证?当我重新加载页面时,console.logdebugger 都不会点击它
  • @xameeramir templateLoaded 函数将由child-component 元素上的事件绑定触发:&lt;child-component (templateLoaded)="templateLoaded($event)"...$event 实际上是 ChildComponent 发出的 ElementRef。你不能手动触发它,如果必须,你将template变量保存在ParentComponent的一个属性中并在病房后进行验证,你可以尝试Parent中的ngAfterViewChecked钩子
【解决方案2】:

使用 @Output 装饰器或服务,而不是绝望地尝试直接从父组件访问文本区域

子模板

<textarea #childComponentElement #someField="ngModel" name="someName" [(ngModel)]="someModel"></textarea>

子组件

@ViewChild('childComponentElement') el:ElementRef;
@Output() textarea = new EventEmitter();
constructor(){
this.textarea.emit(this.el.nativeElement.value);
}

父模板

<child-component (change)="getdata($event)"></child-component>

父组件

export class ParentComponent {
    getdata(e) {
        console.log(e);
    }
}

【讨论】:

    猜你喜欢
    • 2016-08-28
    • 2019-11-18
    • 1970-01-01
    • 2015-06-16
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    相关资源
    最近更新 更多