Angular 2使用动态<ng-content>自定义自动完成的显示

时间:2017-03-01 00:09:14

标签: angular ionic2

我正在创建一个自动完成组件,我正在试图弄清楚我应该如何处理该项目的“显示”。我已尝试使用ng-content并呈现该项但它失败了。我想要的是一种方式给我们ng-content并将“数据”传递给子内容。当我尝试传递内容时,它总是失败并且说“item”未定义。

<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-content。

有人可以为此建议解决方案吗?如果事情没有意义,请告诉我。

1 个答案:

答案 0 :(得分: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>

NB。我没有测试过这个。请注意data是异步的,最初可能没有定义。

<强> 2。用自定义语法替换Angular的插值

类似的东西:

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

然后在孩子中我会解析上面的字符串来搜索&amp;将__ITEM__替换为其实际值。非常低级,有点反模式(直接DOM操作不受欢迎),感觉就像重新发明轮子一样......

第3。将ng-content替换为TemplateRef

我的理解是,您希望让您的用户提供蓝图,了解每个项目在自动填充建议中的显示方式。我想你会想要动态地重复提供的标记。

我不知道您可以使用ng-content轻松完成此操作(例如,您无法执行<ng-content *ngFor="...">)。使用TemplateRef会更容易。

要将项目“blueprint”标记作为TemplateRef获取,请将其包装在<template>标记中:

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

您需要使用以下标识来识别模板:

然后在自动填充组件中,您可以使用@ContentChild装饰器获取模板:

  • 使用模板变量名称(引号):@ContentChild('itemTemplate') itemTpl
  • 或指令类(无引号):@ContentChild(itemTemplateDir) itemTpl

最后,您可以使用ViewContainerRef.createEmbeddedView(templateRef)根据自己的规则打印模板。