Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a method on a Angular Web Component (Custom Element)

I have created an Angular Web Component like below

@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');
  }

}

and in my app module

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);

  }
}

everything is working fine and I have embedded it in a simple HTML page like below

<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>

Now I want to call the open method on it. I can't find a way for that

 <script>
        const button = document.querySelector('#button');
        button.addEventListener('click', () => {
            console.log('button Click');
            const slider = document.querySelector('#slider');
            console.log(slider);
            slider.open();
        });
    </script>
like image 862
Reza Avatar asked Oct 13 '18 22:10

Reza


2 Answers

In Angular 8 I just did

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

And it worked

like image 81
Drew Landgrave Avatar answered Oct 11 '22 16:10

Drew Landgrave


I faced the same problem with you. Using setter like the example above is not working. But If you add @Input() on your setter, you can call that setter to call your method.

@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');
  }
}

Your client javascript code should be as follows.

<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>

Also if you want to retrieve async data on your method and put them on any property, you can get a ChangeDetectorRef from constructor and call ChangeDetectorRef.detectChanges method. If you do not, component html do not know any changes on property.

like image 25
Koray Bayram Avatar answered Oct 11 '22 15:10

Koray Bayram