ContentChildren,获取组件和本机元素

时间:2017-05-24 14:25:59

标签: angular

我一直在寻找Angular的文档和源代码的年龄,但到目前为止还没有运气。

import {
  ContentChildren,
  QueryList
} from '@angular/core';
import { AwesomeComponent } from './awesome.component';

@Component({
  selector: 'cool-dad',
  templateUrl: './cool-dad.template.html'
})
export class CoolDadComponent {
  @Input() loop = false;
  @Input() automatic = false;
  @ContentChildren(AwesomeComponent) items: QueryList<AwesomeComponent>;

  someFunc() {
    this.items.forEach(item => { console.log(item)});
  }
}

使用上面的代码我得到了对组件的引用,我可以设置它的属性并调用它的公共方法。这很好,但我还需要访问它的html属性,例如宽度,高度等。

import {
  ContentChildren,
  ElementRef,
  QueryList
} from '@angular/core';
import { AwesomeComponent } from './awesome.component';

@Component({
  selector: 'cool-dad',
  templateUrl: './cool-dad.template.html'
})
export class CoolDadComponent {
  @Input() loop = false;
  @Input() automatic = false;
  @ContentChildren(AwesomeComponent, { read: ElementRef }) items: QueryList<AwesomeComponent>;

  someFunc() {
    this.items.forEach(item => { console.log(item)});
  }
}

使用上面的代码我得到了native元素,因此我可以访问所有的html属性,但是我放弃了对组件方法的所有访问权。

我怎样才能同时获得两者?

2 个答案:

答案 0 :(得分:3)

只需在AwesomeComponent:

的构造函数中声明以下内容即可
constructor(public elem: ElementRef) {}

这样您就可以访问公共属性elem并访问每个组件的html属性:

someFunc() {
 this.items.forEach(item => {console.log(item.elem.nativeElement.style.someHTMLProperty)});
}

答案 1 :(得分:1)

在我自己的项目中进行黑客攻击之后,我意识到为什么它不会以任何明显的方式本地支持:这是一个坏主意。

如果CoolDadComponent实际上可以更改AwesomeComponent的HTML属性,那么显然需要对该组件做出各种假设,并且封装会变得很糟糕。此外,视图封装规则可能使样式复杂化。

这样做的正确方法是让CoolDadComponent使用@ContentChildren并在AwesomeComponent个实例上设置属性。这些实例应该操纵自己的HTML,最好是在模板中或至少使用Renderer

export class CoolDadComponent {
// Other stuff as in OP
  @ContentChildren(AwesomeComponent) items: QueryList<AwesomeComponent>;
  someFunc() {
    this.items.forEach(item => item.configure({prop1: 'value', prop2: 'value'}));
  }
}

AwesomeComponent

export class AwesomeComponent {
// Other stuff
  public configure(options: MyOptionsInterface) {
    // Set related properties
  }

如果CoolDadComponent(顺便说一下该名称的奖励积分)只是直接在AwesomeComponent上设置个别属性,它也会起作用。