2017-03-01 42 views
0

我正在創建一個自動完成組件,我試圖弄清楚我該如何處理該項目的「顯示」。我試過使用ng-content並渲染該項目,但失敗。我想要的是給我們的方式ng-content並將「數據」傳遞給子內容。當我嘗試傳遞內容時,它總是失敗,並說「項目」未定義。Angular 2自定義動態顯示自動完成<ng-content>

<input-auto-complete 
    [data]="searchResults" 
    (onItemSelected)="onItemSelected($event)" 
    (onSearch)="onSearch($event)"> 
     {{item.Name}} 
</input-auto-complete> 

總之,我創造,做自動完成/搜索的輸入,但我不能想出一個好辦法,讓人們可以自定義他們想如何顯示結果。

我使用的離子,但我的模板的樣子:

<ion-searchbar 
      [(ngModel)]="search" 
      (ionInput)="updateSearch()" 
      (ionCancel)="dismiss()"> 
</ion-searchbar> 
<ion-list> 
    <ion-item *ngFor="let item of data" 
      tappable 
      (click)="onItemSelected(item)"> 
     <!-- i found a way to do something like this where they can pass a function to display --> 
     <ng-container *ngIf="!display"> 
      <pre>{{item|json}}</pre> 
      </ng-container> 
      <ng-container *ngIf="display"> 
      {{display(item)}} 
      </ng-container> 


      <!-- could not get this to work this would be my preference allow people to put whatever in here and it would get rendered and passed "item" --> 
     <!-- if i enable this it breaks <ng-content ></ng-content> -> 
    </ion-item> 
</ion-list> 

當這使得它崩潰,並表示無法讀取的未定義的名稱。它不會將任何內容傳遞給ng內容。

任何人都可以爲此提出解決方案嗎?讓我知道如果事情沒有意義。

+0

項目渲染時可能尚未初始化。你試過'item。?Name' – pixelbits

+0

我現在沒有使用任何「async」數據。我有'searchResults'硬編碼到一個數組。 – Nix

回答

1

有趣的問題。不幸的是,我沒有提供解決方案,但是我在這裏發佈了這個空間和格式的文章。

您的代碼不起作用,因爲item孩子(自動完成)的範圍內唯一定義,它在的背景下進行評估。因此,在父項中評估item.Name時,item未定義。

我看不到一個簡單的解決方案。基本上你想要編譯一個字符串的能力 - <input-auto-complete>元素的內容 - 就像它是另一個模板一樣 - <input-auto-complete>的模板。

這裏有一對夫婦的想法,我希望能幫助(他們都不理想,遺憾的是):

1暴露孩子的屬性和方法的父模板

你可以這樣做通過在孩子上聲明template reference variable

<input-auto-complete #ac> 
    <!-- Now you can access the data from the autocomplete via ac.data --> 
    <ul> 
    <li *ngFor="let item of ac.data">{{ item.name }}</li> 
    </ul> 
</input-auto-complete> 

注意:我沒有測試過這個。請注意,data是異步的,最初可能未定義。

2.更換角的插值與您的自定義語法

喜歡的東西:

<input-auto-complete> 
    <div>__ITEM__</div> 
</input-auto-complete> 

然後在孩子我會分析上面的字符串搜索&其實際值替換__ITEM__。非常低級別,有點反模式(直接DOM操作令人不悅),感覺像是重新發明了輪子...

3。用TemplateRef

這是我的理解是,你想讓你的用戶提供了每個項目將在自動完成建議顯示的藍圖更換ng-content。我想你會想動態地重複提供的標記。

我不知道你可以用ng-content輕鬆做到這一點(例如你不能做<ng-content *ngFor="...">)。 TemplateRef會更容易。

爲了獲得該項目的「藍圖」標記爲TemplateRef,包裝在一個<template>標籤:您需要識別模板

<input-auto-complete> 
    <template #itemTemplate> 
    <div>__ITEM__</div> 
    </template> 
</input-auto-complete> 

  • 無論是模板變量,即<template #itemTemplate>ng-bootstrap modal這樣做)。
  • 或者自定義指令,即<template itemTemplateDir>ng-bootstrap tabs這樣做)。

然後在自動完成組件,您可以得到模板的保持與@ContentChild裝飾:

  • 使用模板變量名稱(包括引號):@ContentChild('itemTemplate') itemTpl
  • 或者指令類(沒有引號):@ContentChild(itemTemplateDir) itemTpl

最後,您可以根據自己的規則打印出模板ViewContainerRef.createEmbeddedView(templateRef)