2016-09-23 12 views
0

カスタムコンポーネントを使用するhtmlファイルがあります。カスタムコンポーネントは、bind()メソッドを呼び出してデータを取得します。したがって、コンポーネントがバインドされると、データが取得され、それに応じてプロパティが設定されます。このコンポーネントにはSave()メソッドもあります。このメソッドは、呼び出されるとオブジェクトをデータベースに送信する必要があります。カスタムコンポーネントのデータ/メソッドへのアクセス

私の外側のhtmlファイルで、このカスタムコンポーネントをインポートしました。だから私は、カスタムコンポーネントを持っているし、私はこのように(カスタムコンポーネントの一部ではない)送信ボタンを持っている:

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

私はカスタムコンポーネントビューにボタンを持っていない理由は、そのビューからです必ずしも同じボタンを持つわけではないので、コンポーネントを拡張不可能にします。

submitCustomComponentData()メソッドは、基本的に、コンポーネントVM内にあるupdateメソッドを呼び出します。

ページが読み込まれると、すべてが完璧に実行されます。データが取り込まれ、私のすべての入力は前のデータ(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

はそうのように、ディスパッチ・質問のコンポーネントを注入します:

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

また、コンポーネントであるupdatedbのメソッドを呼び出す必要がありclick.trigger方法があります。その時点で、コンポーネント(すでにbind()で作成された同じインスタンスを持つはずです)は、そのオブジェクトをDBに送信する必要があります。

何らかの理由でオブジェクトが空であるため、エラーが発生します。コンポーネント内の関数はthis.myObjectを取得し、それをDBに送信しています。私は、私の外側のVM(コンポーネントVMではない)からコンポーネントのthisインスタンスを失っている更新機能を呼び出すと思う。私はそれが問題だと思う。それが問題ならば、それを修正する方法は不明だ。どんな助けも素晴らしいだろう!

私はGistで簡単なバージョンを作成しようとしました。 https://gist.run/?id=f07b2eaae9bec27acda296189585ea6c

答えて

1

in the documentationの説明があります。

アウレリアの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イベントをサブスクライブし、私たちは貯蓄を進める必要があるかどうかを確認することができます。このため、各インスタンスには一意のID(番号、ハッシュ、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}`); 
    } 
} 
関連する問題