在Aurelia中,我可以绑定我的自定义元素调用的包含视图模型的函数吗?

时间:2016-08-20 14:46:42

标签: javascript aurelia aurelia-binding aurelia-templating aurelia-framework

我有一个自定义元素,它将接受用户输入,点击[保存]按钮,我想将信息传递给父视图模型,这样我就可以将它发送到服务器并转到下一部分。我打算简化这个例子:

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

3 个答案:

答案 0 :(得分:15)

你有两种选择。您可以使用自定义事件处理此问题,或者您可以使用Anj在其答案中提到的call绑定来执行此操作。您使用哪一个取决于您的实际用例。

如果您希望自定义元素能够在父虚拟机上调用方法并传递自定义元素的数据 ,那么您应该使用自定义事件,如下所示:{ {3}}:

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);
  }
} 

您基本上会附加您需要传递自定义事件的detail属性所需的任何数据。在事件绑定声明中,您可以将$event作为参数添加到函数中,然后在事件处理程序中检查$ event的detail属性(如果您还可以通过$event.detail想要的)。

如果您希望自定义元素能够在父虚拟机上调用方法并从父虚拟机(或从其他自定义元素或其他内容)传入数据,那么您应该使用call绑定。您可以通过在绑定声明(foo.call="myMethod(myProperty)"中指定它们来指定将传递给方法的参数。这些参数来自声明绑定的VM上下文,而不是来自Custom Element的VM)。

答案 1 :(得分:10)

我能够通过aurelia docs hub稍稍解决这个问题。我不知道可能涉及的所有细微差别,但是对于这个简单的例子,我能够通过以下简单的改变来修复它:

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

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

Here is the documentation from aurelia website.

答案 2 :(得分:0)

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

父级ViewModel

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

父视图

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

子视图

<template bindable="generator">
${generator({myParam:"hello"})}
</template>