Вызов Angular метода веб-компонента (CustomElement) - PullRequest
2 голосов
/ 09 июля 2020

У меня есть эти два примера:

Пример 1:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})

export class AppComponent {
  options:any = {isOpen: false };

  logOptions() {
    console.log(this.options);
  }

}

Пример 2:

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})

export class AppComponent {
  options:any = {isOpen: false };

  @Input() logOptions() {
    console.log(this.options);
  }

}

в html:

<app-root></app-root>

<script>
  document.querySelector('app-root').logOptions();
</script>

В примере 1 возвращает ошибку: document.querySelector(...).logOptions is not a function

В примере 2 возвращает: undefined

Есть ли у кого-нибудь идеи?

1 Ответ

1 голос
/ 17 июля 2020

Это немного поздно, но если вам это все еще нужно, есть несколько способов заставить его работать.

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html'
})

export class AppComponent {

    // @Input() << see comments below
    options: any = {isOpen: false };
    
    // This will NOT be available outside the component, in plain JS
    logOptions() {
        console.log(this.options);
    }

    // This will work ONLY if options is @Input()
    @Input()
    logOptions2() {
        console.log(this.options);
    }
    
    // This property will always provide correct data
    // Ideally a getter should not be @Input() though
    @Input()
    get logOptions3() {
        return this.options;
    }
}

Вы можете получить к ним доступ с помощью простого JavaScript кода как

const logComponentOptions = () => {
    const el = document.querySelector('app-root');
    // el.logOptions(); << Error
    el.logOptions2(); // works ONLY if options is @Input()
    console.log(el.logOptions3); // WORKS
    console.log(el.options); // if options is @Input()
}
  1. Таким образом, свойство logOptions3 всегда можно использовать для получения options из простого javaScript кода. Но семантически неверно (a getter as @Input())
  2. Первый метод logOptions() недоступен извне, так как НЕ отмечен @Input()
  3. Метод logOptions2() доступен, но может печатать только правильное значение, ЕСЛИ options также помечено @Input()
  4. Но если вы отметите свойство options как @Input(), вы можете получить прямой доступ к нему, а не обертывать его в другой метод
  5. Наконец, если вы просто создадите @Input() options = false, вы также сможете получить к нему доступ как к простому атрибуту из HTML, а также
<app-root options="false"></app-root>

Обновить

Если вы хотите передать данные в компонент, вы можете просто предоставить свойство setter с помощью @Input. Затем вы можете установить значение извне компонента с помощью JavaScript

@Input()
public set myData(value: MyDataType) {
    // validation & logic if any
    this._myData = value;
}

// Then in JavaScript
const el = document.querySelector('app-root');
el.myData = {a: 10, b: true, c: 'my data object' }
...