Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aurelia - call function on nested component

Tags:

aurelia

I want to call a child component's function from its parent. I have a way to do it, but I want to know if I'm missing a better way.

From Ashley Grant's blog post about accessing a custom element's viewModel from a custom attribute, I see that Aurelia adds au to the element and you can access the viewModel through that. So, if I add a nested component with a ref, like this:

<template>
    <nested-element ref="childElement"></nested-element>
</template>

I can call a function on it like this:

this.childElement.au.controller.viewModel.someFunction();

This feels roundabout. I was hoping I would be able to access a nested element's viewModel through the parameters to a hook that the parent implements, such as created(owningView, myView) but I can't find a path to it.

Have I missed a better way?

Edit: I forgot to add that I need a return value from the function I'm calling, so having access to the viewmodel itself is preferable

like image 285
mgiesa Avatar asked Nov 27 '16 03:11

mgiesa


2 Answers

ref gives you the element. view-model.ref gives you the element's view model.

<template>
    <nested-element view-model.ref="childViewModel"></nested-element>
</template>

Call it like this in the parent view-model:

this.childViewModel.someFunction();
like image 200
Jeff G Avatar answered Oct 17 '22 03:10

Jeff G


If you only have one instance of the nested-element or don't care if multiple nested-elements respond to the event. Then you could use standard Javascript event functionality for this:

bar.html

<template>
  <h1>${value}</h1>
    <input type="text" value.bind="value"></input>
    <foo>text</foo>
</template>

bar.ts

import {bindable} from 'aurelia-framework';
export class Bar {

  @bindable value;

  public valueChanged(newValue, oldValue) {
    var event = new CustomEvent("some-event-name", { "detail": { message: "Hello from Bar", oldValue, newValue } });
    document.dispatchEvent(event);
  }
}

foo.html

<template>
  <h1>${value}</h1>
</template>

foo.ts

import {bindable} from 'aurelia-framework';

export class Foo {
  constructor() {
    document.addEventListener("some-event-name", (e) => {
      console.log('hello here is Foo, recieved event from Bar : ', e);
    }, true);
  }
}
like image 45
Erik Lieben Avatar answered Oct 17 '22 04:10

Erik Lieben