我有一个使用自定义组件的 html 文件。自定义组件通过 bind() 方法获取数据。因此,当组件被绑定(bind)时,它会获取数据并相应地设置属性。该组件还有一个 Save() 方法,调用该方法时,应将对象提交到数据库。
现在,在我的外部 html 文件中,我已经导入了这个自定义组件。所以我有自定义组件,然后有一个提交按钮(不是自定义组件的一部分),如下所示:
<custom-component></custom-component>
<button click.trigger="submitCustomComponentData()"></button>
我在自定义组件 View 中没有按钮的原因是该 View 并不总是具有相同的按钮,这使得组件不可扩展。
submitCustomComponentData()
方法基本上调用我的组件 VM 中的更新方法。
现在,当页面加载时,一切都运行得很完美。数据被拉入,我的所有输入都预先填充了以前的数据(来自数据库)。一切都很好。但是,当我调用 submitCustomComponentData()
方法(或单击按钮)时,我收到错误,因为该对象未填充。就好像我失去了实例或其他东西。
以下是一些重要部分的片段:
这就是我的外部 html 文件的样子。它由自定义组件组成。
<template>
<require from="resources/components/dispatch-questions/dispatch-questions"></require>
<section class="pages au-animate">
<div class="row" id="dispatch-questions">
<dispatch-questions></dispatch-questions>
</div>
</section>
</template>
为此,VM 会注入(inject)调度问题组件,如下所示:
constructor(private router: Router, private dq: DispatchQuestions) {
}
它还有一个 click.trigger 方法,该方法应该调用组件中的 updateDB 方法。此时,组件(应该已经具有在 bind() 上创建的相同实例)应该将该对象提交到数据库。
但是我收到错误,因为由于某种原因,该对象是空的。组件中的功能是抓取 this.myObject
并将其提交到数据库。我认为当我从外部虚拟机(而不是组件虚拟机)调用更新函数时,我会丢失组件的 this
实例。我认为这就是问题所在..如果这就是问题所在,则不确定如何解决它。任何帮助都会很棒!
我尝试在 Gist 上创建一个简单版本。 https://gist.run/?id=f07b2eaae9bec27acda296189585ea6c
最佳答案
对此有一个解释 in the documentation .
The General Rule for Aurelia's DI Use
Everything is an application-level singleton except for those things which are classified as "components", essentially custom elements, custom attributes and view-models created through the router or composition engine. You can change the lifetime of router and composition created components through explicit configuration.
我建议使用 EventAggregator 而不是注入(inject)。这种方法确保了灵 active 、可扩展性并防止了紧耦合。
关于EventAggregator:#1 Walkthrough by Dwayne Charrington , Documentation , Contact Manager Tutorial .
以下是在您的场景中演示它的要点:https://gist.run/?id=f66eaa12e4183a72a7a3cc01ce3a8fb5
app.js
假设我们想要使用多个 Component
自定义组件实例。为此,我们可以发布带有关联数据的 component:save
事件。
import { inject } from "aurelia-framework";
import { EventAggregator } from 'aurelia-event-aggregator';
@inject(EventAggregator)
export class App {
components = [
{ id: 1, name: 'Component #' },
{ id: 2, name: 'Component #' },
{ id: 3, name: 'Component #' }
];
constructor(eventAggregator) {
this.eventAggregator = eventAggregator;
}
SubmitData(opts) {
this.eventAggregator.publish('component:save', opts);
}
// ...
}
组件.js
在这里我们可以订阅component:save
事件并检查是否应该继续保存。因此,每个 Component
实例都应该有一个唯一的标识(数字、哈希值、uid 等)。
注意:detached
方法中有一个重要的清理部分,官方文档中没有明确提及。这就是为什么我首先列出了 Dwayne Charrington 的博客文章。
import { inject, bindable } from 'aurelia-framework';
import { EventAggregator } from 'aurelia-event-aggregator';
@inject(EventAggregator)
export class Component {
@bindable
id;
object = {};
constructor(eventAggregator) {
this.eventAggregator = eventAggregator;
}
bind() {
this.object = {
"Name": `My name ${this.id}`,
"Age": 21
};
console.log(`component ADDED: #${this.id}`);
this.subscriber = this.eventAggregator.subscribe('component:save', data => {
if (data.id === this.id || data.all === true) {
this.SubmitObjectToDatabase();
console.log(`component:save SAVED: #${this.id}`, this.object.Name);
} else {
console.log(`component:save PASSED: #${this.id}`);
}
});
}
SubmitObjectToDatabase() {
console.log(`SubmitObjectToDatabase has been called: #${this.id}`);
}
detached() {
// cleanup
this.subscriber.dispose();
console.log(`component REMOVED: #${this.id}`);
}
}
关于javascript - 访问自定义组件数据/方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39670825/