Angular 2:如何在嵌套组件上调用方法?

时间:2015-11-20 20:07:25

标签: web-component angular shadow-dom

我正在尝试在我的Angular 2组件中声明的元素上调用函数。 问题是我不知道如何从我的JS代码中检索元素。 如果我可以将元素从模板传递给JS代码,它可以工作,但是 使用document.querySelector不会返回任何内容。

示例代码(plunk):

@View({
  template: `
    <div>
      <span id="p1">{{name}}</span>
      <span #p2>{{name}}</span>
    </div>
  `,
  encapsulation: ViewEncapsulation.Native
})
export class Person {
  sayHello(e) {
    p1 = document.querySelector('p1');
    console.log('p1:', p1)
    p2 = document.querySelector('p2');
    console.log('p2:', p2)

    alert('VanillaId: ' + (p1 ? p1.innerHTML : 'null') +
          '\nAngularId: ' + (p2 ? p2.innerHTML : 'null'));
  }
}

我怀疑它与暗影dom有关,但我不知道如何做 获取影子根并使用它来进行查询。 this似乎没有曝光 任何有用的东西都可以访问dom。

1 个答案:

答案 0 :(得分:5)

使用ElementRef在此处查看http://plnkr.co/edit/LISYnq?p=preview

我确实玩过你的傻瓜:

  

我不知道如何从我的JS代码中检索元素

让我感到震惊的是,您可以在 js code 中设置组件状态,然后使用属性绑定进行变异/显示,并与事件进行通信。

如果您提供更具体的用例,我们可以提供更多建议。无论如何,继承人的代码:

person.ts

//a simple person component
import {Component, View, ViewEncapsulation, Input, ElementRef} from 'angular2/angular2'

@Component({
  selector: 'my-person',
  inputs: ['name'],
  template: `
    <pre>
      <span> (Unsuspecting shadow dom node minding its own business)</span>
      <span #p0el> Name      : {{name}}</span>
      <span #p1el> Passed in : {{p1}}</span>
    </pre>
  `,
  encapsulation: ViewEncapsulation.Native
})

export class Person {
  public p1:string = "...";
  @Input('name') name:string;
  constructor (elementRef: ElementRef) {
    this.elementRef = elementRef;
  }
  sayHello(str) {
    this.p1 = str;
    this.elementRef.nativeElement.shadowRoot.querySelector('span').textContent = "BAM!"


  }
}

app.ts

//our root app component
import {Component, View, CORE_DIRECTIVES, ViewEncapsulation} from 'angular2/angular2'
import {Person} from './person'

@Component({
  selector: 'my-app',
  template: `
    <div>
      <!-- Passing the element here works fine -->
      <button (click)="person.sayHello('Clicked!') && person.name = 'Clicky name'">Test</button>

      <my-person #person [name]="'World'"></my-person>
    </div>`,
  directives: [CORE_DIRECTIVES, Person],
  encapsulation: ViewEncapsulation.Native
})
export class App {
  test(personComponent: Person) {
  }
}