2017-11-10 9 views
0

私は、別のコンポーネントのサブクラスであるポリマーコンポーネントのセットを持っています。私は、サブクラスのテンプレートに基づいてスーパークラスのテンプレートを設定したいと思います。サブクラス基本クラス挿入ポイントを埋めるポリマー要素

<!-- control.html --> 
<media-tabs tabs-title="Alternative input"> 
    <template> 
    <media-blackout></media-blackout> 
    <media-slates></media-slates> 
    <media-playlists></media-playlists> 
    <media-queue></media-queue> 
    </template> 
</media-tabs> 
<!-- media-tabs.html --> 
<paper-card heading="[[tabsTitle]]" class="fill-h fill-v"> 
    <div class="card-content"> 
    <paper-tabs id="tabs" selected="{{selectedIndex}}" selectable> 
    </paper-tabs> 
    <iron-pages id="content" selected="{{selectedIndex}}"> 
    </iron-pages> 
    </div> 
</paper-card> 
// media-tabs.js 
ready() { 
    super.ready(); 
    this.selectedIndex = 0; 
    const template = this.querySelector('template'); 
    const instance = this._stampTemplate(template); 
    const tabs = Array.from(instance.children); 
    tabs.forEach((elm) => { 
    const content = elm.constructor.template.content; 
    this.$.tabs.appendChild(content.querySelector('#title')); 
    this.$.content.appendChild(content.querySelector('#content')); 
    }); 
} 
<!-- media-tab.html --> 
<paper-tab id="title"></paper-tab> 
<div id="content"></div> 
<!-- media-blackout.html --> 
<span id="title">Blackout</span> 
<div id="content"> 
    <p>Lorem ipsum dolor sit amet</p> 
</div> 
<!-- repeat above for media-playlists, media-queue, and media-slates --> 
// media-blackout.js -- is a subclass of media-tab 
static get template() { 
    if (!superTemplate) { 
    const thisTemplate = Polymer.DomModule.import(this.is, 'template'); 
    superTemplate = MediaTab.template.cloneNode(true); 
    const title = thisTemplate.content.querySelector('#title').textContent; 
    const content = thisTemplate.content.querySelector('#content'); 
    const children = Array.from(content.children); 

    superTemplate.content.querySelector('#title').innerHTML = title; 
    children.forEach((child) => { 
     superTemplate.content.querySelector('#content').appendChild(child); 
    }); 
    } 
    return superTemplate; 
} 
// repeat above for media-playlists, media-queue, and media-slates 

:(。残念ながらなし溶液で、同様の問題への解決策を探して他の誰かのためhereを参照してください)使い方は次のようになりますこの設定は機能します。しかし、template()ゲッターはmedia-tabサブクラスでと同じです。サブクラスの実装の詳細を知る必要のあるスーパークラスのコードを使わずに、そのロジックをスーパークラスに移動する方法を探したいと思います。

私はスーパークラス(例えば、 const title = this.templateTitleElement.textContent;)からプルする必要があるだろう二つのフィールドのgetterを作成しようとしました

、しかし私の実装はいくつかの方法(スタックオーバーフローをもたらす)内の要素のtemplateプロパティを突くか、あるいはしようどちらか利用可能になる前に要素にアクセスしてください(例:return this.$.title;)。

答えて

0

私の以前のソリューションは、タブのコンテンツの中からイベントをバブリングの問題を持っていたので、私は別の解決策を考え出すことを余儀なくされた。

<!-- control.html --> 
<media-tabs tabs-title="Alternative input" on-play-slate="handlePlayTapped"> 
    <media-blackout></media-blackout> 
    <media-slates></media-slates> 
    <media-playlists></media-playlists> 
    <media-queue></media-queue> 
</media-tabs> 

あなたは、私が削除した見ることができますmedia-tabs宣言のテンプレート。

<!-- media-tabs.html --> 
<paper-card heading="[[tabsTitle]]"> 
    <div class="card-content"> 
    <paper-tabs id="tabs" selected="{{selectedIndex}}" selectable></paper-tabs> 
    <iron-pages id="content" selected="[[selectedIndex]]"> 
     <slot></slot> 
    </iron-pages> 
    </div> 
</paper-card> 

私は鉄のページに<slot>挿入ポイントを追加したことがわかります。

// media-tabs.js 
ready() { 
    super.ready(); 
    const children = Array.from(this.children); 
    children.forEach((child) => { 
    const template = Object.getPrototypeOf(child.constructor).template; 
    const instance = this._stampTemplate(template); 
    instance.$.title.innerHTML = child.tabTitle; 
    this.$.tabs.appendChild(instance.$.title); 
    }); 
} 

今、私だけではなくpaper-tabsiron-pagesの両方よりも、paper-tabs要素に子を追加します。 Object.getPrototypeOf(child.constructor)は、childのスーパークラスのコンストラクタを返します。これは、子のスーパークラスがid="title"の要素と、tabTitleという要素を持つと仮定すると、であるため、子のスーパークラスがMediaTabであると仮定しているわけではありません。

<!-- media-tab.html --> 
<paper-tab id="title"></paper-tab> 
// media-tab.js 
static get properties() { 
    return { 
    tabTitle: String, 
    }; 
} 

media-tabテンプレートは、任意のより多くのコンテンツのdiv要素が含まれていない、とスーパークラスはmedia-tabs.jsで参照tabTitleプロパティを定義します。

<!-- media-blackout.html --> 
<p>Lorem ipsum dolor sit amet</p> 
<!-- repeat above for media-playlists, media-queue, and media-slates --> 

media-tabサブクラスは、もは​​や彼らはコンテンツのみを持って、HTMLでそのタブのタイトルを保存していません。

// media-blackout.js 
class MediaBlackout extends MediaTab { 
    // ... 

    static get properties() { 
    return { 
     tabTitle: { 
     type: String, 
     value: 'Blackout', 
     readOnly: true, 
     }, 
    }; 
    } 
} 
// repeat above for media-playlists, media-queue, and media-slates 

代わりspanにサブクラスのタイトルを持つのではなく、クラスのプロパティとして定義されています。

このソリューションは、ミックスインを使用していない、とのイベントがアプリのトップにMediaTab要素できるバブルアップの中から解雇されています。

0

私はmixinを使って解決策を考え出しました。それは古典的なOOPの継承ではありませんが、同じ関数を4回複製することなく機能します。

// title-content-mixin.js 
const titleContentMixin = (function() { 
    const titleContentMixin = (superClass, options = {}) => { 
    const titleQuery = options.titleQuery || '#title'; 
    const contentQuery = options.contentQuery || '#content'; 
    const superTitleQuery = options.superTitleQuery || titleQuery; 
    const superContentQuery = options.superContentQuery || contentQuery; 

    return class TitleContentMixin extends superClass { 
     static get template() { 
     if (this.is === superClass.is || superClass.is.length === 0) return; 

     const thisTemplate = Polymer.DomModule.import(this.is, 'template') 
      .cloneNode(true); 
     const superTemplate = superClass.template.cloneNode(true); 
     const title = thisTemplate.content.querySelector(titleQuery).textContent; 
     const content = thisTemplate.content.querySelector(contentQuery); 
     const children = Array.from(content.children); 

     superTemplate.content.querySelector(superTitleQuery).innerHTML = title; 
     children.forEach((child) => { 
      superTemplate.content.querySelector(superContentQuery) 
       .appendChild(child); 
     }); 
     return superTemplate; 
     } 
    }; 
    }; 

    return Polymer.dedupingMixin(titleContentMixin); 
})(); 
// media-blackout.js 
class MediaBlackout extends titleContentMixin(MediaTab) { 
    // ... 
} 
// repeat above for media-playlists, media-queue, and media-slates 
関連する問題