如何调用 Angular Web 组件(自定义元素)上的方法

问题描述 投票:0回答:7

我创建了一个如下所示的 Angular Web 组件

@Component({
  selector: 'dlx-slider',
  templateUrl: './slider.component.html',
  styleUrls: ['./slider.component.scss'],
  encapsulation: ViewEncapsulation.Native,
})
export class SliderComponent implements OnInit {
  open() {
    console.log('open');
  }

  close() {
    console.log('close');
  }
    
}

在我的应用程序模块中

export class AppModule {

  constructor(private injector: Injector) {}
  
  ngDoBootstrap() {
      this.defineElement(SliderComponent, 'dlx-slider');
  }
  
  private defineElement(component: any, elementName: string) {
    const el = createCustomElement(component, { injector: this.injector });
    customElements.define(elementName, el);
  }

}

一切工作正常,我已将其嵌入到一个简单的 HTML 页面中,如下所示

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>TMIBot</title>
        <base href="/">
    
        <meta name="viewport" content="height=device-height, width=device-width, initial-scale=1.0, user-scalable=no">
    
        <title>Test Angular Elements</title>
        <link rel="stylesheet" href="https://urltomy/dist/dlx-styles-1.0.css">
    </head>
    
    <body>
        <button id="button">Open Slider </button>
        <dlx-slider id="slider"></dlx-slider>
        <script type="text/javascript" src="https://urltomy/dist/dlx-chatbot-1.0.js"></script>
    </body>
</html>

现在我想调用它的

open
方法。我找不到办法

<script>
const button = document.querySelector('#button');
button.addEventListener('click', () => {
  console.log('button Click');
  const slider = document.querySelector('#slider');
  console.log(slider);
  slider.open();
});
</script>
angular web-component custom-element
7个回答
5
投票

在 Angular 8 中我刚刚这么做了

@Input()
doFoo() {
   console.log('we did it');
}

而且成功了


4
投票

使用setter并赋值来调用函数可能不太漂亮。

所以我做了一点改变:

@Input()
  get close() {
    return () => doClose();
  }

现在我们可以调用

close
函数而不是赋值。


4
投票

为什么不在元素本身上公开该方法?

@Component({
    selector: 'ng-comp-ce',
    templateUrl: './ng-comp.component.html',
    styleUrls: ['./ng-comp.component.scss'],
})
export class NGComponentCustomElement {

    constructor(private element: ElementRef) {
    }

    ngOnInit() {
        this.element.nativeElement.myFunc = () => this.myFunc();
    }
  
    myFunc() {
      console.log('hello from component');
    }
}

并在页面中用JS调用它

 document.querySelector('ng-comp-ce').myFunc();

3
投票

我也遇到了和你一样的问题。像上面的例子一样使用 setter 是行不通的。但是如果你在 setter 上添加 @Input() ,你就可以调用该 setter 来调用你的方法。

@Component({
  selector: 'slider',
  templateUrl: './slider.component.html',
  styleUrls: ['./slider.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class SliderComponent implements OnInit {
  @Input()
  set open(state:string) {
    doOpen();
  }

  @Input()
  set close(state:string) {
    doClose();
  }

  doOpen() {
    console.log('open');
  }

  doClose() {
    console.log('close');
  }
}

您的客户端 JavaScript 代码应如下所示。

<script>
    const button = document.querySelector('#button');
    button.addEventListener('click', () => {
        console.log('button Click');
        const slider = document.querySelector('#slider');
        console.log(slider);
        // Call open method
        slider.open = 'open';
        // Call close method
        slider.close = 'close';
    });
</script>

此外,如果您想检索方法上的异步数据并将它们放在任何属性上,您可以从构造函数获取 ChangeDetectorRef 并调用 ChangeDetectorRef.detectChanges 方法。如果不这样做,组件 html 将不知道属性发生任何变化。


1
投票

Setter
Getter
可以提供调用该方法的选项。

在ts文件中

      set state(state:string) {
        console.log("state changed ", state);
      }

      get state() {
        return "IN"; 
      }

调用set属性来调用openState setter方法。

<script>
        const button = document.querySelector('#button');
        button.addEventListener('click', () => {
            console.log('button Click');
            const slider = document.querySelector('#slider');
            console.log(slider);
            //slider.open();
             setTimeout(() => {
           slider.setAttribute('state', 'OUT');
           }, 1000);
        });
    </script>

1
投票

角9

在您的 Web 组件中

<my-slider>
我们可以将方法定义为 setter - 另外我们可以以传统方式定义事件

    @Output() myEvent = new EventEmitter<any>();
 
    @Input() set myFunction(data: {str: string, n: number}) {    
      // ... your code

      this.myEvent.emit({xyz:'abc', data});  // fire example event
    }

在您的 Angular 项目中,您可以按如下方式使用此组件

html 模板(注意 - 我们可以以角度方式处理事件!)

    <my-slider #myslider (myEvent)="sliderEventHandler($event)" ></my-slider>

ts 文件(我们使用

@ViewChild
以避免使用 ID)

    @ViewChild('myslider') myslider: any;
    
    // and in some method - we execute web-component function
    this.myslider.nativeElement.myFunction = {str: "Alice in ...", n: 10}; 

在事件处理程序中,我们得到

CustomEvent
对象,我们可以从中获取事件数据,如下所示

    sliderEventHandler(event: CustomEvent) {
      console.log('event data!', event.detail);
    }

0
投票

你可以这样做:

export class MyClass {
    
    constructor(private host: ElementRef) {
        // https://github.com/angular/angular/issues/22114#issuecomment-569311422
        this.host.nativeElement.myMethod = this.myMethod.bind(this);
    }

    @Input()
    public myMethod(): void {
        this.doSomethingHere();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.