访问自定义组件数据/方法

Accessing Custom Component Data/Methods

本文关键字:方法 数据 组件 自定义 访问      更新时间:2023-09-26

我有一个使用自定义组件的html文件。自定义组件通过bind()方法获取数据。因此,当组件被绑定时,它获取数据并相应地设置属性。该组件还有一个Save()方法,当调用该方法时,应该将对象提交给数据库。

现在,在我的外部html文件中,我导入了这个自定义组件。所以我有一个自定义组件然后我有一个提交按钮(不是自定义组件的一部分)像这样:

<custom-component></custom-component>
<button click.trigger="submitCustomComponentData()"></button>

我在自定义组件视图中没有按钮的原因是因为该视图并不总是具有相同的按钮,这会使组件不可扩展。

submitCustomComponentData()方法基本上调用我的组件VM中的更新方法。

现在,当页面加载时,一切都运行完美。数据被拉进来,我的所有输入都预先填充了以前的数据(来自DB)。一切都很好。但是,当我调用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被注入dispatch-questions组件,如下所示:

constructor(private router: Router, private dq: DispatchQuestions) {
    }

它也有一个点击。trigger方法,该方法应该调用组件中的updateDB方法。此时,组件(应该已经拥有在bind()上创建的相同实例)应该将该对象提交给DB。

但是我得到了一个错误,因为某些原因,对象是空的。组件中的功能是抓取this.myObject并将其提交给DB。我想当我从外部VM(不是组件VM)调用更新函数时,我正在失去组件的this实例。我想这就是问题所在,如果是这个问题,我不知道该怎么解决。任何帮助都太棒了!

我试着在Gist上创建一个简单的版本。https://gist.run/?id=f07b2eaae9bec27acda296189585ea6c

文档中对此有解释。

奥蕾莉亚使用DI的一般规则

所有的东西都是应用级的单例,除了那些被归类为"组件"的东西,本质上是通过路由器或组合引擎创建的自定义元素、自定义属性和视图模型。你可以通过显式配置来改变router和composition创建的组件的生存期。

我建议使用EventAggregator而不是注入。这种方法确保了灵活性、可扩展性和防止紧耦合。

关于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);
  }
  // ...
}

component.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}`);
  }
}