获取html元素(#, @ViewChild @ViewChildren ElementRef)

转自: http://www.open-open.com/lib/view/open1461113267205.html

只有极少的情况需要直接操作 DOM 。 angular2 提供了一系列牛X的高阶APIs来完成你期望的 DOM 操作,例如:queries。利用 angular2 提供的这些APIs有如下优势:

  • 单元测试里不直接操作 DOM 可以降低测试复杂度,使你的测试用例跑的更快

  • 把你的代码从浏览器中解藕,允许你在任何渲染环境里跑你的程序,譬如: web worker ,或者完全离开浏览器(比如:运行在服务器端,亦或是 Electron 里)

当你手动操作 DOM 时,就失去了上述优势,而且代码越写越不易读。

从 AngularJS 1 (或者压根没写过 Angular 的人)转型的朋友,我能猜到大概哪些场景是你们想直接操作 DOM 的。那我们来一起看下这些状况,我来演示下如何用queries重构她们。

场景 一:当需要获取当前组件模版里的某一个元素时

假设你的组件模版里有一个 input 标签,并且你希望在组件加载后立即让这个 input 自动获取焦点

你或许已经知道通过 @ViewChild / @ViewChildren 这两个queries可以获取当前组件模版里的内嵌组件。但在这个例子里,你需要的是获取一个普通的 HTML 元素,而非一个组件。一开始估计你就直接注入 ElementRef 来操作了:

直接操作 ElementRef (不推荐)

@Component({
  selector: 'my-comp',
  template: `
    <input type="text" />
    <div> Some other content </div>
  `
})
export class MyComp {
  constructor(el: ElementRef) {
    el.nativeElement.querySelector('input').focus();
  }
}

其实我想说的是,这种做法 没必要 。

解决方案: @ViewChild 配合local template variable

程序员们没想到的是除了组件本身,其他原生元素也是可以通过 local variable 获取的。在写组件时,我们可以直接在组件模版里给这个 input 标签加标记(譬如: #myInput ), 然后把标记传给 @ViewChild 用来获取该元素。当组件初始化后,你就可以通过 renderer 在这个 input 标签上执行 focus 方法了。

@ViewChild 配合 local variable (推荐)

@Component({
  selector: 'my-comp',
  template: `
    <input #myInput type="text" />
    <div> Some other content </div>
  `
})
export class MyComp implements AfterViewInit {
  @ViewChild('myInput') input: ElementRef;

  constructor(private renderer: Renderer) {}

  ngAfterViewInit() {
    this.renderer.invokeElementMethod(this.input.nativeElement,    
    'focus');
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值