我创建了一个如下所示的 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 8 中我刚刚这么做了
@Input()
doFoo() {
console.log('we did it');
}
而且成功了
使用setter并赋值来调用函数可能不太漂亮。
所以我做了一点改变:
@Input()
get close() {
return () => doClose();
}
现在我们可以调用
close
函数而不是赋值。
为什么不在元素本身上公开该方法?
@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();
我也遇到了和你一样的问题。像上面的例子一样使用 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 将不知道属性发生任何变化。
Setter
和 Getter
可以提供调用该方法的选项。
set state(state:string) {
console.log("state changed ", state);
}
get state() {
return "IN";
}
<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>
在您的 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);
}
你可以这样做:
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();
}
}