如何在组件模板中选择元素?

本文翻译自:How can I select an element in a component template?

Does anybody know how to get hold of an element defined in a component template? 有人知道如何掌握组件模板中定义的元素吗? Polymer makes it really easy with the $ and $$ . 使用$$$可以使Polymer变得非常容易。

I was just wondering how to go about it in Angular. 我只是想知道如何在Angular中进行操作。

Take the example from the tutorial: 从教程中获取示例:

import {Component} from '@angular/core'

@Component({
    selector:'display'
    template:`
     <input #myname(input)="updateName(myname.value)"/>
     <p>My name : {{myName}}</p>
    `

})
export class DisplayComponent {
    myName: string = "Aman";
    updateName(input: String) {
        this.myName = input;
    }
}

How do I catch hold of a reference of the p or input element from within the class definition? 如何从类定义中抓住对pinput元素的引用?


#1楼

参考:https://stackoom.com/question/2DAxR/如何在组件模板中选择元素


#2楼

You can get a handle to the DOM element via ElementRef by injecting it into your component's constructor: 您可以通过将ElementRef注入到组件的构造函数中来通过ElementRef获取DOM元素的句柄:

constructor(myElement: ElementRef) { ... }

Docs: https://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html 文件: https//angular.io/docs/ts/latest/api/core/index/ElementRef-class.html


#3楼

import { Component, ElementRef, OnInit } from '@angular/core';

@Component({
  selector:'display',
  template:`
   <input (input)="updateName($event.target.value)">
   <p> My name : {{ myName }}</p>
  `
})
class DisplayComponent implements OnInit {
  constructor(public element: ElementRef) {
    this.element.nativeElement // <- your direct element reference 
  }
  ngOnInit() {
    var el = this.element.nativeElement;
    console.log(el);
  }
  updateName(value) {
    // ...
  }
}

Example updated to work with the latest version 示例已更新以使用最新版本

For more details on native element, here 有关本机元素的更多详细信息,请单击此处


#4楼

Instead of injecting ElementRef and using querySelector or similar from there, a declarative way can be used instead to access elements in the view directly: 代替注入ElementRef并从那里使用querySelector或类似的方法,可以使用声明性方法直接访问视图中的元素:

<input #myname>
@ViewChild('myname') input; 

element 元件

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

StackBlitz example StackBlitz示例

  • @ViewChild() supports directive or component type as parameter, or the name (string) of a template variable. @ViewChild()支持将指令或组件类型作为参数,或模板变量的名称(字符串)。
  • @ViewChildren() also supports a list of names as comma separated list (currently no spaces allowed @ViewChildren('var1,var2,var3') ). @ViewChildren()还支持以逗号分隔列表的名称列表(当前不允许使用空格@ViewChildren('var1,var2,var3') )。
  • @ContentChild() and @ContentChildren() do the same but in the light DOM ( <ng-content> projected elements). @ContentChild()@ContentChildren()的功能相同,但使用的是DOM( <ng-content>投影元素)。

descendants 子孙

@ContentChildren() is the only one that allows to also query for descendants @ContentChildren()是唯一一个还可以查询后代的人

@ContentChildren(SomeTypeOrVarName, {descendants: true}) someField; 

{descendants: true} should be the default but is not in 2.0.0 final and it's considered a bug {descendants: true}应该是默认值,但不在2.0.0 final中,因此 被认为是错误
This was fixed in 2.0.1 此问题已在2.0.1中修复

read

If there are a component and directives the read parameter allows to specify which instance should be returned. 如果有组件和指令,则read参数允许指定应返回哪个实例。

For example ViewContainerRef that is required by dynamically created components instead of the default ElementRef 例如,动态创建的组件而不是默认的ElementRef需要ViewContainerRef

@ViewChild('myname', { read: ViewContainerRef }) target;

subscribe changes 订阅更改

Even though view children are only set when ngAfterViewInit() is called and content children are only set when ngAfterContentInit() is called, if you want to subscribe to changes of the query result, it should be done in ngOnInit() 即使仅在ngAfterViewInit()时才设置视图子级,而仅在ngAfterViewInit()时才设置内容子级, ngAfterContentInit() ,如果要订阅查询结果的更改,则应在ngOnInit()

https://github.com/angular/angular/issues/9689#issuecomment-229247134 https://github.com/angular/angular/issues/9689#issuecomment-229247134

@ViewChildren(SomeType) viewChildren;
@ContentChildren(SomeType) contentChildren;

ngOnInit() {
  this.viewChildren.changes.subscribe(changes => console.log(changes));
  this.contentChildren.changes.subscribe(changes => console.log(changes));
}

direct DOM access 直接DOM访问

can only query DOM elements, but not components or directive instances: 只能查询DOM元素,而不能查询组件或指令实例:

export class MyComponent {
  constructor(private elRef:ElementRef) {}
  ngAfterViewInit() {
    var div = this.elRef.nativeElement.querySelector('div');
    console.log(div);
  }

  // for transcluded content
  ngAfterContentInit() {
    var div = this.elRef.nativeElement.querySelector('div');
    console.log(div);
  }
}

get arbitrary projected content 获得任意的投影内容

See Access transcluded content 请参阅访问包含的内容


#5楼

For people trying to grab the component instance inside a *ngIf or *ngSwitchCase , you can follow this trick. 对于试图在*ngIf*ngSwitchCase获取组件实例的*ngSwitchCase ,您可以按照以下技巧进行操作。

Create an init directive. 创建一个init指令。

import {
    Directive,
    EventEmitter,
    Output,
    OnInit,
    ElementRef
} from '@angular/core';

@Directive({
    selector: '[init]'
})
export class InitDirective implements OnInit {
    constructor(private ref: ElementRef) {}

    @Output() init: EventEmitter<ElementRef> = new EventEmitter<ElementRef>();

    ngOnInit() {
        this.init.emit(this.ref);
    }
}

Export your component with a name such as myComponent 使用诸如myComponent的名称导出组件

@Component({
    selector: 'wm-my-component',
    templateUrl: 'my-component.component.html',
    styleUrls: ['my-component.component.css'],
    exportAs: 'myComponent'
})
export class MyComponent { ... }

Use this template to get the ElementRef AND MyComponent instance 使用此模板获取ElementRef AND MyComponent实例

<div [ngSwitch]="type">
    <wm-my-component
           #myComponent="myComponent"
           *ngSwitchCase="Type.MyType"
           (init)="init($event, myComponent)">
    </wm-my-component>
</div>

Use this code in TypeScript 在TypeScript中使用此代码

init(myComponentRef: ElementRef, myComponent: MyComponent) {
}

#6楼

 */
import {Component,ViewChild} from '@angular/core' /*Import View Child*/

@Component({
    selector:'display'
    template:`

     <input #myname (input) = "updateName(myname.value)"/>
     <p> My name : {{myName}}</p>

    `
})
export class DisplayComponent{
  @ViewChild('myname')inputTxt:ElementRef; /*create a view child*/

   myName: string;

    updateName: Function;
    constructor(){

        this.myName = "Aman";
        this.updateName = function(input: String){

            this.inputTxt.nativeElement.value=this.myName; 

            /*assign to it the value*/
        };
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值