Dans Aurelia, puis-je lier une fonction à partir de mon modèle de vision contenant pour être appelé par mon élément personnalisé?

J'ai un élément personnalisé qui prendra la saisie des utilisateurs et, en appuyant sur le bouton [Enregistrer], je souhaite transmettre des informations au modèle de vision parent afin de pouvoir l'envoyer au serveur et passer à la section suivante. Je vais simplifier cela par exemple:

my-element.js :

 import { customElement, bindable } from 'aurelia-framework'; @customElement('my-element') @bindable('save') export class MyElement { } 

my-element.html :

 <template> <button click.delegate="save()">Click this</button> </template> 

parent-view-model.js :

 export class ParentViewModel { parentProperty = 7; parentMethod() { console.log(`parent property: ${this.parentProperty}`); } } 

parent-view-model.html :

 <template> <require from="./my-element"></require> <div class="content-panel"> <my-element save.bind="parentMethod"></my-element> </div> </template> 

Pour une démonstration, voir (app.js et app.html représentent parent-view-model.js et parent-view-model.html):

Https://gist.run/?id=96b203e9ca03b62dfb202626c2202989

Ça marche! Genre de. Malheureusement, this semble être lié à my-element au lieu de parent-view-model , donc dans cet exemple, ce qui est imprimé dans la console est: parent property: undefined . Ça ne marchera pas.

Je sais que je peux utiliser EventAggregator pour faciliter la communication entre l'élément personnalisé et le modèle de vue, mais si je peux l'aider, j'aimerais éviter la complexité ajoutée.

Vous avez deux options pour cela. Vous pouvez gérer cela en utilisant des événements personnalisés, ou vous pouvez le faire en utilisant la liaison d' call que Anj a mentionnée dans sa réponse. Lequel vous utilisez dépend de votre cas d'utilisation réelle.

Si vous souhaitez que l'élément personnalisé puisse appeler une méthode sur votre VM parent et extraire des données à partir de l'élément personnalisé, vous devez utiliser un événement personnalisé tel qu'indiqué dans ce principe: https://gist.run/?id= Ec8b3b11f4aa4232455605e2ce62872c :

App.html:

 <template> <require from="./my-element"></require> <div class="content-panel"> <my-element save.delegate="parentMethod($event)"></my-element> </div> parentProperty = '${parentProperty}' </template> 

App.js:

 export class App { parentProperty = 7; parentMethod($event) { this.parentProperty = $event.detail; } } 

My-element.html:

 <template> <input type="text" value.bind="eventDetailValue" /> <button click.delegate="save()">Click this</button> </template> 

My-element.js:

 import { inject, customElement, bindable } from 'aurelia-framework'; @customElement('my-element') @inject(Element) export class MyElement { eventDetailValue = 'Hello'; constructor(element) { this.element = element; } save() { var event = new CustomEvent('save', { detail: this.eventDetailValue, bubbles: true }); this.element.dispatchEvent(event); } } 

Vous associez fondamentalement toutes les données dont vous avez besoin pour transmettre la propriété de detail de l'événement personnalisé. Dans le cas de la déclaration de liaison, vous ajouteriez $event comme paramètre à la fonction, puis vérifiez la propriété de detail de $ event dans votre gestionnaire d'événements (vous pouvez également passer $event.detail si vous le souhaitez).

Si vous souhaitez que l'élément personnalisé puisse appeler une méthode sur votre VM parentale et avoir des données passées à partir de la VM parent (ou d'un autre élément personnalisé ou quelque chose), vous devez utiliser la liaison d' call . Vous pouvez spécifier les arguments qui seront transmis à la méthode en les spécifiant dans la déclaration de liaison ( foo.call="myMethod(myProperty)" . Ces arguments proviennent du contexte VM où la liaison est déclarée et non à partir de la VM de Custom Element ).

J'ai pu résoudre cela après avoir parcouru un peu le hub aurelia docs. Je ne connais pas toutes les nuances qui peuvent être impliquées, mais pour cet exemple simple, j'ai pu le réparer en faisant le changement simple suivant:

Dans parent-view-model.html (ou app.html dans l'exemple gist-run), modifiez save.bind="parentMethod" pour save.call="parentMethod()"

Je ne suis toujours pas sûr de savoir comment transmettre les données de l'élément personnalisé dans la méthode parentale du modèle d'affichage.