Могу ли я в Aurelia связать функцию из моей содержащей модели представления для вызова моим пользовательским элементом?

javascript aurelia aurelia-binding aurelia-templating aurelia-framework

10216 просмотра

2 ответа

У меня есть пользовательский элемент, который будет принимать пользовательский ввод, и при нажатии кнопки [сохранить] я хочу передать информацию в родительскую модель представления, чтобы я мог отправить ее на сервер и перейти к следующему разделу. Я собираюсь упростить это, например, ради:

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>

Для демонстрации см. (App.js и app.html представляют parent-view-model.js и parent-view-model.html):

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

Оно работает! Что-то вроде. К сожалению, thisкажется, связан с my-elementвместо parent-view-model, так что в этом примере, что напечатано в консоли: parent property: undefined. Это не будет работать.

Я знаю, что могу использовать EventAggregator, чтобы облегчить некоторую связь между пользовательским элементом и моделью представления, но если я могу помочь, я бы хотел избежать дополнительной сложности.

Автор: Anj Источник Размещён: 08.11.2019 11:27

Ответы (2)


15 плюса

Решение

У вас есть два варианта для этого. Вы можете справиться с этим с помощью пользовательских событий, или вы можете сделать это с помощью callпривязки, упомянутой Анж в своем ответе. Какой из них вы используете, зависит от вашего фактического варианта использования.

Если вы хотите, чтобы пользовательский элемент мог вызывать метод на вашей родительской виртуальной машине и передавать данные из пользовательского элемента, тогда вам следует использовать пользовательское событие, как показано в этом гисте: 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;
  }
}

мой-element.html:

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

мой-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);
  }
} 

В основном вы должны прикрепить любые данные, которые вам нужно передать, к detailсвойству пользовательского события. В объявлении привязки события вы добавляете $eventв качестве параметра функцию, а затем проверяете detailсвойство $ event в вашем обработчике события (вы также можете просто передать его, $event.detailесли хотите).

Если вы хотите, чтобы пользовательский элемент мог вызывать метод на вашей родительской виртуальной машине и получать данные, передаваемые из родительской виртуальной машины (или из другого пользовательского элемента или чего-то еще), вам следует использовать callпривязку. Вы можете указать аргументы, которые будут переданы методу, указав их в объявлении привязки ( foo.call="myMethod(myProperty)"эти аргументы поступают из контекста виртуальной машины, в которой объявляется привязка, а не из виртуальной машины пользовательского элемента).

Автор: Ashley Grant Размещён: 20.08.2016 04:46

10 плюса

Я смог решить эту проблему после небольшого троллинга через концентратор aurelia docs. Я не знаю всех нюансов, которые могут быть связаны, но для этого простого примера я смог это исправить, выполнив следующие простые изменения:

В parent-view-model.html (или app.html в примере gist-run) измените save.bind="parentMethod"наsave.call="parentMethod()"

Однако я все еще не уверен, как передать данные из пользовательского элемента в метод родительской модели представления.

Вот документация с сайта aurelia.

Автор: Anj Размещён: 20.08.2016 03:44
Вопросы из категории :
32x32