2017-07-17 53 views
0

我正在研究一個表示表的Ractive js組件。它工作正常,但最近我添加了一些功能:過濾器,狀態欄,左列複選框,表頭。這個表格組件在整個應用程序中都被使用。Composable Ractive js組件

問題是,在不同的地方,我只需要這些功能的一些組合。在目前的實現中,我在模板中有很多ifs,我想擺脫它們。

目前我想使用decorator pattern,但不知道如何實現這一點,尤其是因爲我需要弄亂核心表模板。

表模板:

{{#if status_bar}} 
<table class="list-status"> 
    <tbody> 
     <tr> 
     <td><input type="checkbox" checked="{{.select_all}}"></td> 
     <td> 
      {{#if has_filters}} 
      <span>Показать:</span> 
      {{#each filters:i}} 
       <button on-tap="@this.fire('activateFilter', event, i)" {{#if active}}class="active"{{/if}}>{{title}}</button> 
      {{/each}} 
      {{/if}} 
      {{#if ready}} 
      <span class="badge lists-badge">{{ collection.total_count }}</span> 
      {{#if selected.length > 0}} 
       <span class="badge lists-badge" style="background-color: red;">{{ selected.length }}</span> 
      {{/if}} 
      {{/if}} 
     </td> 
     </tr> 
    </tbody> 
    </table> 
{{/if}} 

<table class="{{class}}"> 
    {{#if header}} 
    <thead> 
     <tr> 
     {{^hideSelectColumn}} 
      <th></th> 
     {{/hideSelectColumn}} 
     {{#each titles}} 
      <th class={{class}}>{{title}}</th> 
     {{/each}} 
     </tr> 
    </thead> 
    {{/if}} 
    <tbody> 
    {{#if ready}} 
     {{#each diff_create:i}} 
     <tr class="just-created"> 
      {{^hideSelectColumn}} 
      <td class="{{firstColumnClass}}"> 
       <div style="position: relative;"></div> 
      </td> 
      {{/hideSelectColumn}} 
      {{>pending}} 
     </tr> 
     {{/each}} 
     {{#if diff_create.length > 0}} 
     <tr> 
      <td colspan={{column_count}}></td> 
     </tr> 
     {{/if}} 
     {{#each page_models}} 
     <tr {{#if mfd}} class='mfd' {{/if}}> 
      {{^hideSelectColumn}} 
      <td class="{{firstColumnClass}}"> 
       <input type="checkbox" class="list-checkbox" name='{{selected}}' value='{{@index}}'/> 
       <div style="position: relative;"></div> 
      </td> 
      {{/hideSelectColumn}} 
      {{>content}} 
     </tr> 
     {{/each}} 
     {{^page_models}} 
     <tr> 
      <td style='text-align:center; font-weight: bold; font-size: 15px' colspan={{column_count}}>Пусто!</td> 
     </tr> 
     {{/}} 
    {{/if}} 
    {{^ready}} 
     <tr> 
     <td style='text-align:center; font-weight: bold; font-size: 15px' colspan={{column_count}}>Загрузка...</td> 
     </tr> 
    {{/ready}} 
    </tbody> 
</table> 

<div class="pages"> 
    {{#if pages_more_than_one}} 
    <ul class="pagination"> 
     {{#if has_prev_page}} 
     <li class="arrow-left"><a on-tap='prevPage'><span class="icon-arrow-left4"></span></a></li> 
     {{/if}} 
     {{#each pages}} 
     <li class='{{@index+1==current_page ? "active": ""}}'><a on-tap='@this.fire("goToPage", @index+1)'>{{@index+1}}</a></li> 
     {{/each}} 
     {{#if has_next_page}} 
     <li class="arrow-right"><a on-tap='nextPage'><span class="icon-arrow-right8"></span></a></li> 
     {{/if}} 
    </ul> 
    {{/if}} 
    <div class="pages-count"> 
    <select class="form-control" value="{{collection.perpage}}"> 
     <option value='2'>2</option> 
     <option value='5'>5</option> 
     <option value='10'>10</option> 
     <option value='15'>15</option> 
     <option value='20'>20</option> 
     <option value='25'>25</option> 
    </select>&nbsp; 
    </div> 
</div> 

在此先感謝。

回答

1

Ractive有named yields您可以在其中定義佈局中的佔位符,並讓消費組件定義該佈局中的內容。把它看作一個佈局機制。

一個簡單的例子是一個模式,其中有一個標題,正文和頁腳,它們可能對每個實例都不相同。一個模態組件只能被定義爲模態的佈局(認爲是空引導模態)和類似於可插入位置的一組收益。

const Modal = Ractive.extend({ 
    template: ` 
    <div class="modal"> 
     <div class="modal__header">{{yield header }}</div> 
     <div class="modal__body">{{yield body }}</div> 
     <div class="modal__footer">{{yield footer }}</div> 
    </div> 
    ` 
}) 

在使用組件上,您使用佈局組件並定義這些位置中的內容。請注意,產量內容可能是任何東西,甚至其他組件。

const Page = Ractive.extend({ 
    components: { Modal }, 
    template: ` 
    <div class="page"> 
     <div class="page__stuff"> 
     ... 
     </div> 

     <Modal> 
     {{#partial header }} 
      This is the header 
     {{/partial}} 

     {{#partial body }} 
      This is the body 
     {{/partial}} 

     {{#partial footer }} 
      This is the footer 
     {{/partial}} 
     </Modal> 

    </div> 
    ` 
}); 

在你的情況下,可以打破你表成組分(即過濾器,狀態欄,左列複選框,表頭),並定義一個佈局組件。然後,只要你需要它,你就可以使用佈局組件,無論你在哪裏都可以隨時隨地使用佈局組件。

更高級的功能是Anchors。與ractive.attachChild()ractive.link()一起,您可以隨時手動將組件錨定到錨點。它本質上就是Ractive如何在組件上看到模板上的組件時綁定數據。除此之外,該功能在API上公開。

+0

非常感謝約瑟夫,嘗試過濾器,它的工作原理!在這種情況下,你對事件處理有什麼看法?現在我直接更改Filters組件中的共享集合,也許最好是處理表本身中的事件? – Maxim

+0

@Maxim在這種情況下,我會讓組件不修改數據。我會讓它們發出事件並讓消費組件(答案中的「頁面」)處理與事件相關的數據操作。這使組件通用,同時將所有邏輯移動到一個地方。我認爲在React領域,他們稱之爲[「表現」和「容器」組件。](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0) – Joseph