在 Aurelia 中,我可以从包含的视图模型中绑定一个函数以供我的自定义元素调用吗? [英] In Aurelia, can I bind a function from my containing view-model to be called by my custom element?
问题描述
我有一个接受用户输入的自定义元素,在单击 [save] 按钮时,我想将信息传递给父视图模型,以便我可以将其发送到服务器并移至下一部分.例如,我将简化此操作:
my-element.js
:
import { customElement, bindable } from 'aurelia-framework';@customElement('我的元素')@bindable('保存')导出类 MyElement { }
my-element.html
:
<button click.delegate="save()">点击这个</button>模板>
parent-view-model.js
:
导出类ParentViewModel {父属性 = 7;父方法(){console.log(`父属性:${this.parentProperty}`);}}
parent-view-model.html
:
<require from="./my-element"></require><div class="content-panel"><my-element save.bind="parentMethod"></my-element>
模板>
演示参见(app.js 和 app.html 分别代表 parent-view-model.js 和 parent-view-model.html):
https://gist.run/?id=96b203e9ca03b62dfb202626c2202989
它有效!的种类.不幸的是,this
似乎绑定到 my-element
而不是 parent-view-model
,所以在这个例子中,什么打印到控制台是:父属性:未定义
.那行不通.
我知道我可以利用 EventAggregator 来促进自定义元素和视图模型之间的一些通信,但如果我能帮助它,我想避免增加的复杂性.
对此您有两个选择.您可以使用自定义事件来处理这个问题,也可以使用 Anj 在他的回答中提到的 call
绑定来完成.您使用哪一种取决于您的实际用例.
如果您希望自定义元素能够调用父虚拟机上的方法并将数据传出自定义元素,那么您应该使用自定义事件,如下面的要点所示:https://gist.run/?id=ec8b3b11f4aa4232455605e2ce62872c>:
app.html:
<require from="./my-element"></require><div class="content-panel"><my-element save.delegate="parentMethod($event)"></my-element>
parentProperty = '${parentProperty}'模板>
app.js:
导出类 App {父属性 = 7;父方法($事件){this.parentProperty = $event.detail;}}
my-element.html:
<input type="text" value.bind="eventDetailValue"/><button click.delegate="save()">点击这个</button>模板>
my-element.js:
import { inject, customElement, bindable } from 'aurelia-framework';@customElement('我的元素')@inject(元素)导出类 MyElement {eventDetailValue = '你好';构造函数(元素){this.element = 元素;}节省() {var event = new CustomEvent('保存', {详细信息:this.eventDetailValue,气泡:真实});this.element.dispatchEvent(事件);}}
您基本上可以在自定义事件的 detail
属性上附加您需要传递的任何数据.在事件绑定声明中,您可以将 $event
作为参数添加到函数中,然后检查事件处理程序中 $event 的 detail
属性(您也可以通过$event.detail
(如果需要).
如果您希望自定义元素能够调用父虚拟机上的方法并从父虚拟机(或其他自定义元素或其他东西)传入数据,那么您应该使用 call代码>绑定.您可以通过在绑定声明 (
foo.call="myMethod(myProperty)"
) 中指定将传递给方法的参数.这些参数来自声明绑定的 VM 上下文,而不是来自自定义元素的 VM).
I have a custom element which will take user input, and on [save] button click, I want to pass information to the parent view-model so I can send it to the server and move to the next section. I'm going to simplify this for example's sake:
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>
For a demo, see (app.js and app.html represent parent-view-model.js and parent-view-model.html):
https://gist.run/?id=96b203e9ca03b62dfb202626c2202989
It works! Kind of. Unfortunately, this
seems to be bound to my-element
instead of parent-view-model
, so in this example, what is printed to console is: parent property: undefined
. That will not work.
I know I can utilize the EventAggregator to facilitate some communication between the custom element and the view-model, but if I can help it I'd like to avoid the added complexity.
You have two options for this. You could handle this using Custom Events, or you can do it using the call
binding that Anj mentioned in his answer. Which one you use depends on your actual use case.
If you want the custom element to be able to call a method on your parent VM and pass data out of the custom element, then you should use a Custom Event as shown in this gist: 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);
}
}
You would basically attach any data you need to pass on the detail
property of the Custom Event. In the event binding declaration, you would add $event
as a parameter to the function and then check the detail
property of $event in your event handler (you could also just pass $event.detail
if you wanted).
If you want the custom element to be able to call a method on your parent VM and have data passed in from the parent VM (or from another custom element or something), then you should use the call
binding. You can specify arguments that will be passed to the method by specifying them in the binding declaration (foo.call="myMethod(myProperty)"
. These arguments come from the VM context where the binding is being declared, not from the Custom Element's VM).
这篇关于在 Aurelia 中,我可以从包含的视图模型中绑定一个函数以供我的自定义元素调用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!