【问题标题】:Accessing Custom Component Data/Methods访问自定义组件数据/方法
【发布时间】:2016-09-23 23:13:58
【问题描述】:

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

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

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

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

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

现在,当页面加载时,一切运行完美。数据被拉入,我的所有输入都预先填充了以前的数据(来自数据库)。一切都很好。但是,当我调用 submitCustomComponentData() 方法(或单击按钮)时,我收到一个错误,因为该对象未填充。这就像我失去了实例或其他东西。

这里是一些重要部分的sn-p:

这就是我的外部 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) {
    }

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

但由于某种原因,我收到了一个错误,该对象是空的。组件中的函数是抓取this.myObject 并将其提交给数据库。我想当我从外部 VM(而不是组件 VM)调用更新函数时,我丢失了组件的 this 实例。我认为这就是问题所在。如果这是问题所在,不确定如何解决。任何帮助都会很棒!

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

【问题讨论】:

    标签: javascript typescript aurelia


    【解决方案1】:

    in the documentation 有一个解释。

    Aurelia 使用 DI 的一般规则

    除了那些被归类为“组件”的东西,本质上是自定义元素、自定义属性和通过路由器或组合引擎创建的视图模型之外,所有东西都是应用程序级的单例。您可以通过显式配置更改路由器和组合创建的组件的生命周期。

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

    关于 EventAggregator:#1 Walkthrough by Dwayne CharringtonDocumentationContact 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}`);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2012-05-13
      • 1970-01-01
      • 2018-01-02
      • 1970-01-01
      • 2021-11-26
      相关资源
      最近更新 更多