问题描述
我正在访问在线API,并希望使用文本值来填充ngb-typeahead下拉列表。使用Wikipedia的角度引导网站上有一个working example,但是从Wikipedia API返回的数据与我从地理编码API获得的数据不同。我获取的数据以以下格式返回:
{
"suggestions": [
{
"text": "23 Queen Charlotte Drive,Aotea,Porirua,Wellington,5024,NZL","magicKey": "dHA9MCNsb2M9NDMwNzcyNzQjbG5nPTMzI2huPTIzI2xicz0xMDk6NDg1NDQwMzU=","isCollection": false
},{
"text": "23 Queen Mary Avenue,Epsom,Auckland,1023,"magicKey": "dHA9MCNsb2M9NDMwNDY4MjUjbG5nPTMzI2ZhPTE0NDE3OTIjaG49MjMjbGJzPTEwOTo0ODU0NDMyNA==",
我一直尝试通过以下方式访问text
作为响应数据:
return this.http
.get<any>(GIS_URL,{params: GIS_ParaMS.set('text',term)}).pipe(
map(response => response.suggestions)
);
我还阅读了有关处理响应数据的Angular教程here,但示例中的不同之处在于它们获取的是Hero数组,而我获取的是包含建议数组的对象。
键入的内容如下:
HTML
<fieldset class="form-inline">
<div class="form-group">
<label for="typeahead-http">Search for a wiki page:</label>
<input id="typeahead-http" type="text" class="form-control mx-sm-3" [class.is-invalid]="searchFailed" [(ngModel)]="model" [ngbTypeahead]="search" placeholder="Wikipedia search" />
<small *ngIf="searching" class="form-text text-muted">searching...</small>
<div class="invalid-Feedback" *ngIf="searchFailed">Sorry,suggestions Could not be loaded.</div>
</div>
</fieldset>
<hr>
<pre>Model: {{ model | json }}</pre>
我是新来的,所以详细的答案会很棒。
解决方法
您需要在预输入resultFormatter
(请参考https://ng-bootstrap.github.io/#/components/typeahead/api)上指定inputFormatter
和input
说明
您在服务中的search
方法返回一个建议对象列表,每个对象看起来像:
{
isCollection: ...
magicKey: ...
text: ...
}
但是默认情况下,typeahead控件需要一个字符串列表,因此它会将您的对象显示为[Object object]。
您需要告诉typeahead控件如何从对象中确定字符串值,您可以通过resultFormatter
和inputFormatter
进行操作。
这些输入采用一个函数,该函数以对象作为输入,并以字符串显示值作为输出。
下面的 formatter
是该函数,将为列表中显示的每个项目调用该函数。如果将其扩展为普通函数,则可以在其中放置一个断点,并查看以这种方式调用它。
解决方案
<input id="typeahead-http" ... [inputFormatter]="formatter" [resultFormatter]="formatter"/>
TS文件:
formatter = (item:any) => item.text as string;
更新了Stackblitz
https://stackblitz.com/edit/so-typeahead?file=src%2Fapp%2Ftypeahead-http.ts
后续问题
-
item
在格式化程序中:
考虑:
formatter = (item:any) => item.text as string;
的简写:
function format(item: any){
return item.text as string;
}
他们提前键入控件/指令,以迭代search(..)
返回的项目,并分别调用此方法。结果显示在选择列表中。
-
map(response => response.suggestions)
服务的响应是一个对象,例如:
{ // object
suggestions:
[
{ ...,text: 'Place 1' },{ ...,text: 'Place 2' }
]
}
这是一个包含名为suggestions
的列表的对象。提前输入仅需要一个列表,因此map
转换仅包含list => list的对象。
- 您定义的格式化程序同时输入和结果吗?
是的,因为它已同时分配给模板中的[inputFormatter]
和[resultFormatter]
。
替代答案
映射完全在服务中完成:
return this.http
.get<any>(GIS_URL,{params: GIS_PARAMS.set('text',term)}).pipe(
map(response => response.suggestions.map(suggestion => suggestion.text)),);
每个响应对象都映射到建议列表。
每个建议都使用JS映射映射到其文本值。
如果您不需要访问服务之外的任何其他建议属性,则可以使用此解决方案。