1

できればテンプレートから、古いコンポーネントの場所でコンポーネントを完全に破棄して再インスタンス化する最良の方法は何ですか?

私たちのユースケースは、ビューで使用される一連のバックボーン モデル/コレクションがあることです。ではinit、これらのモデルまたはコレクション イベントの一部をリッスンする場合があります (深い場合もあります)。または、そのモデルに関連する何らかのセットアップ作業を行う場合もあります。ビューでモデル プロパティ全体が変更されたかどうかをリッスンし、イベントのバインドを解除して新しいモデルにバインドし、セットアップ作業をやり直すか、ビューを強制的に破棄して新しいものをその場所に配置するかの 2 つのオプションがあるようです。テンプレートが大幅に、または完全に変更される可能性があるためです。変更の重要性と、ビューの白紙の状態から確実に開始できるようにするため、後者のルートを選択しました。

この時点まで、コンポーネントを条件付きでラップし、ブール値を変更して古いコンポーネントを破棄し、新しいコンポーネントを再レンダリングするようにしました。

HTML

<p>Some stuff that isn't bound to the model: {{prop1}}, {{prop2}}</p>
{{#if isRenderable}}
  <myComponent model="{{model}}" />
{{/if}}

JS

component.set('isRenderable', false); // force `myComponent` to teardown
component.set('model', aDifferentModel); // this often happens in/via template
component.set('isRenderable', true); // force a new `myComponent` to render

これはまともなアプローチですか、それとも私たちはこれをすべて間違っていると考えていますか? 特に私たちのアプリのいくつかの場所で必要なため、より良いオプションが必要なようです.

4

1 に答える 1

3

これを行う 1 つのreset()方法は、コンポーネントのメソッドを使用してデータを変更し、動的テンプレート関数を含めて適切なテンプレートを選択することです。利点の 1 つは、変更しない限りテンプレートを再レンダリングする必要がないことdata.typeです。(ところで、再レンダリングしないコンポーネントのデフォルトの背後にある設計は、データが更新されている場合、すべてを再レンダリングするよりも DOM 値を更新する方が効率的であるということです。 falsey-block トリックは、強制的に更新するために機能しますが、それは常に必要とは限りません)。

実装に固有の詳細が多数ありますが、この例からいくつかのアイデアが得られます。

var Page = Ractive.extend({
    template: function(data, t){
        return data.type ? t.fromId(data.type) : 'loading...'
    }
})

var r = new Ractive({
    el: '#container',
    template: '#template',
    data: { model: datas.person1 },
    components: {
        page: Page
    },
    oninit: function(){
        var page = this.findComponent('page')
        this.observe('model', function(n){
            page.reset(n)
        })
    },
    load: function(load){
        this.set('model', datas[load])
    }
})

これは、さまざまなモデルをレンダリングしているコンポーネントに共有ロジックがある場合、またはロジックがない場合に機能します。

ただし、特定のモデルのビューに固有のオブザーバーとイベント ハンドラーがあるため、モデル タイプごとに異なるコンポーネントを使用したい場合がよくあります。その場合、この例ではダイナミズムを親にレベルアップし、コンポーネントのオプション関数を使用します。

var r = new Ractive({
    el: '#container',
    template: '#template',
    data: datas.person1,
    components: {
        page: function(data){
            return components[data.type]
        }
    },
    load: function(load){
        this.reset( datas[load] )
    }
})
于 2014-09-30T22:30:47.177 に答える