2016-11-17 14 views
0

私は、ユーザーがそれを尋ねたときに特定の機能を実行する必要のある欲求不満なコンポーネントを持っています。つまり、コンポーネントが初期化されているときではなく、後である場合があります。親コンポーネントから子コンポーネント内の関数を呼び出す最も良い方法は?

ractive docs mention events are used to communicate between components and their parentsただし、子から親にバブリングするイベントのコンテキストでのみ。この場合、親は子に対して何かを呼び出さなければなりません。

また、ractive.findComponent()がありますが、例は親から子への通信にはあまり使用されていないようです。

私はFindComponent指定()と作品を使用して、次のスニペットを作りました(「ファイル名を指定して実行コードスニペット」をクリックしその後、「フルページ」)。しかし、私はそれが最適だかわからない:

var coolWidget = Ractive.extend({ 
 
    data: {}, 
 
    template: `<span>Your favorite fruit is {{ fruit }}</span>`, 
 
    data: function(){ 
 
    return { 
 
     fruit: 'banana', 
 
     doCoolThing: function(){ 
 
     var component = this; 
 
     console.log('Going to change fruit...') 
 
     setTimeout(function(){ 
 
      component.set('fruit', 'avocado') 
 
     }, 3 * 1000) 
 
     } 
 
    } 
 
    } 
 
}) 
 

 
var ui = new Ractive({ 
 
    el: '.some-ui', 
 
    data: { name: 'Mike'}, 
 
    components: { 
 
    coolWidget 
 
    }, 
 
    template: ` 
 
    <h1>Hello {{ name}}</h1> 
 
    <button>Press me</button> 
 
    <coolWidget /> 
 
    `, 
 
    oncomplete: function(){ 
 
    var widget = this.findComponent('coolWidget') 
 
    document.querySelector('button').addEventListener('click', function(){ 
 
     widget.get('doCoolThing')(); 
 
    }) 
 
    } 
 
})
<script src="http://cdn.ractivejs.org/latest/ractive.js"></script> 
 
<div class="some-ui"> 
 

 
</div>

親から子コンポーネント内の関数を呼び出すの最良の方法は何ですか?

答えて

1

doCoolThingはトップレベルのオプションであるならば...

var coolWidget = Ractive.extend({ 
    data: {}, 
    template: `<span>Your favorite fruit is {{ fruit }}</span>`, 
    data: function(){ 
    return { 
     fruit: 'banana' 
    } 
    }, 
    doCoolThing: function(){ 
    var component = this; 
    console.log('Going to change fruit...') 
    setTimeout(function(){ 
     component.set('fruit', 'avocado') 
    }, 3 * 1000) 
    } 
}) 

...あなたがそうのようなメソッドを呼び出すことができます。

oncomplete: function(){ 
    var widget = this.findComponent('coolWidget') 
    document.querySelector('button').addEventListener('click', function(){ 
    widget.doCoolThing(); 
    }) 
} 

これはちょうどは感じていない実際には具体的なメリットがあります。doCoolThingcoolWidgetというプロトタイプに載っているため、インスタンス化されるウィジェットの数にかかわらず一度しか作成されません。また、コンテキストバインディングには内部的な悩みがありません。

2

私は@ rich-harrisの答えをコメントで拡張しようとしていましたが、明らかにこれは長すぎます。

あなたの配線もう少し管理RACTIVE持っているしたい場合は、ルート・インスタンスからイベントに、火災購読できます

ウィジェットでonrender:this.coolThingListener = this.root.on('doCoolThing *.doCoolThing', function() { /* cool thing here */ })

ウィジェットでonunrender:this.coolThingListener.cancel()

メインインスタンステンプレート内:<button on-click="doCoolThing">Press me</button>

ボタンを押すと、イベントはルートインスタンスにバブルされます。このインスタンスには、いずれものリスナーがありますイベント(プレーン版とスター付き版を使用すると、ネストされたコンポーネントは、ルートインスタンスのイベントに加えてそれをトリガーできます)。注意すべきことは、コンポーネントイベントハンドラ(coolThingListener)のthisがルートインスタンスになるため、コンポーネント参照を取得するか、矢印関数を使用する必要があります。

onunrenderには、ルートの存続期間中にコンポーネントのインスタンスが複数ポップした場合に、退会があります。

var coolWidget = Ractive.extend({ 
    data: {}, 
    template: `<span>Your favorite fruit is {{ fruit }}</span>`, 
    onrender: function(){ 
    var component = this; 
    // if 'doCoolThing' might fire from another component, add '*.doCoolThing' to listener to matching child component events too 
    this.coolThingListener = this.root.on('doCoolThing', function(){ 
     component.doCoolThing(); 
    }); 
    }, 
    onunrender: function(){ 
    this.coolThingListener.cancel(); 
    }, 
    data: function(){ 
    return { 
     fruit: 'banana' 
    } 
    }, 
    doCoolThing: function(){ 
    console.log('Going to change fruit...') 
    setTimeout(function(){ 
     this.set('fruit', 'avocado') 
    }, 3 * 1000) 
    } 
}) 

var ui = new Ractive({ 
    el: '.some-ui', 
    data: { name: 'Mike'}, 
    components: { 
    coolWidget 
    }, 
    template: ` 
    <h1>Hello {{ name}}</h1> 
    <button on-click="doCoolThing">Press me</button> 
    <coolWidget /> 
    ` 
}) 
+0

ありがとう:

はここで一緒に全体のことです! '' doCoolThing * .doCoolThing''は正しいですか? 'coolWidget doCoolThing'のようなものではないでしょうか? – mikemaccana

+0

@mikemaccanaこの特定のケースでは、イベントがルートから発信されており、名前空間を持たないため、 '* .doCoolThing'を削除できます。子コンポーネントから来る可能性がある場合、イベントはコンポーネント境界を最初に通過するときにイベントが名前空間に成長するため、スター・リスナーはそれを捕捉します(直接の親へのバブル)。スペースで区切られた複数の名前を持つことは、複数のイベントを購読している場合の省略形に過ぎません。 –

+0

あなたのコメントにマッチするあなたのサンプルを更新できますか?それは少し明確になります。また、HTMLではなくaddEventListener()でイベントバインディングを行うことができますか? – mikemaccana

関連する問題