我正在创建一个自动完成组件,我正在试图弄清楚我应该如何处理该项目的“显示”。我已尝试使用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。
有人可以为此建议解决方案吗?如果事情没有意义,请告诉我。
答案 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>
您需要使用以下标识来识别模板:
<template #itemTemplate>
(ng-bootstrap modal会这样做)。<template itemTemplateDir>
(ng-bootstrap tabs会这样做)。然后在自动填充组件中,您可以使用@ContentChild
装饰器获取模板:
@ContentChild('itemTemplate') itemTpl
@ContentChild(itemTemplateDir) itemTpl
最后,您可以使用ViewContainerRef.createEmbeddedView(templateRef)根据自己的规则打印模板。