9

我有一个将接受用户输入的自定义元素,在单击 [save] 按钮时,我想将信息传递给父视图模型,以便将其发送到服务器并移至下一部分。例如,我将对此进行简化:

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 来促进自定义元素和视图模型之间的一些通信,但如果我能帮助它,我想避免增加复杂性。

4

3 回答 3

15

您有两种选择。您可以使用自定义事件来处理这个问题,也可以使用callAnj 在他的回答中提到的绑定来完成。您使用哪一个取决于您的实际用例。

如果您希望自定义元素能够调用父 VM 上的方法并将数据传递出自定义元素,则应使用自定义事件,如以下要点所示:https ://gist.run/?id= ec8b3b11f4aa4232455605e2ce62872c

应用程序.html:

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

    parentProperty = '${parentProperty}'
</template>

应用程序.js:

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

我的元素.html:

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

我的元素.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)"。这些参数来自声明绑定的 VM 上下文,而不是来自自定义元素的 VM)。

于 2016-08-20T16:46:52.210 回答
10

在浏览 aurelia docs hub 一段时间后,我能够解决这个问题。我不知道可能涉及的所有细微差别,但是对于这个简单的示例,我可以通过进行以下简单更改来修复它:

在 parent-view-model.html(或 gist-run 示例中的 app.html)中,更改save.bind="parentMethod"save.call="parentMethod()"

但是,我仍然不确定如何将数据从自定义元素传递到父视图模型的方法中。

这是来自 aurelia 网站的文档。

于 2016-08-20T15:44:47.727 回答
0

要将参数化函数传递给自定义子组件,请编写以下内容(根据文档http://aurelia.io/docs/binding/basics#function-references)。

父视图模型

private _generate(myParam:string) {
    return myParam + " world";
}

父视图

<custom-comp generator.call="_generate(myParam)"></custom-comp>

子视图

<template bindable="generator">
${generator({myParam:"hello"})}
</template>
于 2020-12-04T10:47:03.330 回答