我有一个multiselect-dropdown.html
与它自己的.js,以及一个edit-user.html
与它自己的.js。
当我点击edit-user.html
中的复选框或列表项时,我试图让它在multiselect-dropdown.html
中触发一个函数。
我发现aurelia文档有点缺乏信息。
我不认为我需要粘贴js文件,我只需要指导如何从edit-user.html
中的列表项调用multiselect-dropdown.html
中的函数是否可能?一些提示会有所帮助。
<template>
<div class="dropdown">
<button id="${baseId}"
class="dropdown-toggle form-control input"
type="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false">
<span class="multiselect-dropdown-selection">${textCaption}</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu input"
aria-labelledby="${baseId}"
click.trigger="preventDropDownClose($event)">
<li if.bind="!disableOriginal">
<a>
<label>
<input
type="checkbox"
id="multiselect-dropdown-select-default"
checked.bind="isSelectOriginal">
${textSelectOriginal}
</label>
</a>
</li>
<li>
<a>
<label>
<input
type="checkbox"
id="multiselect-dropdown-select-all"
checked.bind="isSelectAll">
${textSelectAll}
</label>
</a>
</li>
<li role="separator" class="divider"></li>
<li repeat.for="option of options" onmousedown=>
<a>
<label>
<input // This should send a trigger to a function in edit-user.html
type="checkbox"
class="multiselect-dropdown-option"
checked.bind="option.checked"> ${option.name}
</label>
</a>
</li>
</ul>
</div>
</template>
这是edit-user.html
中的多选,如果在edit-user.html
中选中或取消选中复选框,如何调用multiselect-dropdown.html
中的函数?
<div class="form-group user-multiselect-dropdown">
<label for="address" class="regular-15-25">Mina valda adresser</label>
<multiselect-dropdown
options.bind="selectedAddresses"
noun-singular="adress"
noun-plural="adresser">
</multiselect-dropdown>
</div>
你需要使用<multiselect-dropdown>
属性将函数绑定到.call
,如下所示:
<multiselect-dropdown function-name.call="checkboxChanged()"></multiselect-dropdown>
您可以在multiselect-dropdown
的viewmodel中绑定到此,如下所示:
@bindable()
public functionName: () => void; // or without typing if you don't use typescript
注意功能名称的大小写;在HTML中,你用破折号(-
)分隔的是在你的视图模型中的camelCased,例如function-name
成为functionName
现在,只要复选框发生变化,您就需要在viewmodel中调用该函数。你可以使用observe
装饰器@observable
复选框的值,并在它改变时调用该函数。如果要观察对象的属性,则需要使用bindingEngine
。
import { bindable, observable, bindingEngine, autoinject } from "aurelia-framework";
@autoinject
export class Foo {
@bindable()
public functionName: () => void;
@observable()
public checkboxValue: boolean;
public option = {
checked: true;
}
constructor(private bindingEngine: BindingEngine) {}
attached() {
// subscribe to an object property
this.subscription = this.bindingEngine.propertyObserver(this.option, "checked").subscribe(() => {
this.functionName();
}
}
detached() {
// Dispose subscription to avoid memory leak
this.subscription.dispose();
}
// Observe a single field for changes
checkboxValueChanged() {
this.functionName();
}
}
Jesse的答案是两种有效方法之一。另一种方法是从您的自定义元素中调度CustomEvent
,并从使用自定义元素的视图中订阅它。
在multiselect-dropdown.js
内:
// without your JS it's hard to assume what you need, but here's the gist of it
// assuming this method is called in some way in response to a change
onSelectionChanged() {
const detail = {
component: this, // include whatever information the consuming view needs
};
const event = new CustomEvent('select', { bubbles: true, detail });
this.el.dispatchEvent(event); // assuming this.el is the injected Element instance
}
在edit-user.html
:
<multiselect-dropdown select.trigger="handleSelect($event)">
</multiselect-dropdown>
在edit-user.js
:
handleSelect($event) {
const detail = $event.detail;
// do stuff with detail.component or whichever info you included
return false; // stops the event from bubbling further up
}
正如您所看到的,就.call
与派遣自定义事件而言,它们在您可以使用它们解决的问题方面存在很多重叠。
我个人对源自DOM事件的调用的偏好是将它们保留为事件。当您需要在DOM树中进一步传递更改时,它允许您更接近使用HTML的自然方式。
另一方面,.call
导致创建的对象和侦听器更少,并且可能在非常大的应用程序中产生更好的性能(特别是更低的内存使用率)。它还可以减少您在清理/取消传播等方面的担忧。
两者都有自己的时间和地点,在你的情况下使用任何有意义的东西。