google 处 api 不适用于使用 ionic 4 生成的文本字段
google places api doesnt work for the generated text field using ionic 4
下面的代码用于动态添加文本字段,此文本字段是一个 goole places 自动完成列表,我的问题是 goole places api 仅适用于第一个字段并且不起作用。对于生成的字段
.html
<section
[formGroupName]="i"
*ngFor="let tech of form.controls.stations.controls; let i = index">
<ion-button
(click)="removeInputField(i)"
*ngIf="form.controls.technologies.length > 1"
class="ion-no-padding ion-float-right" shape="round" fill="clear">
<ion-icon slot="start" name="close"></ion-icon>Remove</ion-button>
</ion-item-group>
</section>
<div>
<!-- Allow new input field to be generated/added -->
<ion-button
(click)="addNewInputField()"
class="ion-no-padding ion-float-left" shape="round" fill="clear">
<ion-icon slot="start" name="add"></ion-icon> Add a new technology</ion-button>
</div>
.ts
@ViewChild('autoStation', {static: true}) autoStation: any;
ngAfterViewInit(): void {
this.autoCompleteStation.forEach( autoStation => {
autoStation.getInputElement().then(( input: HTMLInputElement) => {
var autocompl = new google.maps.places.Autocomplete(input, {
//somee code
});
}
});
addNewInputField() : void {
const control = this.form.controls.technologies as FormArray;
control.push(this.initTechnologyFields());
}
removeInputField(i : number) : void {
const control = this.form.controls.technologies as FormArray;
control.removeAt(i);
}
[![在此处输入图片描述][1]][1]
[![在此处输入图片描述][2]][2]
我添加了一些图片来大致了解这个问题,第一张图片是我制作的 UI 第二张是什么时候尝试输入城市 google 地方 api 正在工作,但是当我单击添加新城市的按钮时,生成了文本字段,但是 google 地方 api 不起作用,这就是问题所在。
这是我认为您的代码中发生的情况:
将 API 用于通过 *ngFor 创建的组件模板中已有的离子输入的原因很简单 - 在组件的 ngAfterViewInit 生命周期中,您有一个运行的方法在所有这些离子输入中,获取它们的原生输入元素并为它们中的每一个初始化 Places API。
当您使用按钮添加新的离子输入时 - 对于新添加到 DOM 输入的那些,没有任何东西可以帮助初始化位置 API。
要修复 #2,您需要确保 DOM 的此类新添加的离子输入得到初始化的位置 API。
如果您遵循我的回答,您的 you were using ViewChildren and QueryList, which according to Angular.io 习惯于:
...get the QueryList of elements or directives from the view DOM. Any
time a child element is added, removed, or moved, the query list will
be updated, and the changes observable of the query list will emit a
new value.
如果是这样,则意味着您的代码中有:
@ViewChildren('autoStation') autoStationList:QueryList<any>;
每次您添加另一个带有#autostation 标识符的离子输入时,此 autoStationList 都会更新。
这意味着您只需获取此 QueryList 的最后一个子项并为其初始化 Places API。您可以使用 QueryList 的 changes() 方法来做到这一点,您可以订阅该方法,每次列表更改时 - 获取其 "last" 元素,提取输入并初始化位置 API:
ngAfterViewInit(): void {
// here you initialize all ion-input's native inputs that exist in DOM at component view initialization stage:
this.autoCompleteStation.forEach( autoStation => {
autoStation.getInputElement().then(( input: HTMLInputElement) => {
let autocompl = new google.maps.places.Autocomplete(input, {
//some code
})
});
// here you subscribe to changes for the list:
this.autoStationList.changes.subscribe(list => {
// here we need to use "last" property of the list:
list.last.getInputElement().then(( input: HTMLInputElement) => {
var autocompl = new google.maps.places.Autocomplete(input, {
//somee code
})
})
});
}
下面的代码用于动态添加文本字段,此文本字段是一个 goole places 自动完成列表,我的问题是 goole places api 仅适用于第一个字段并且不起作用。对于生成的字段
.html
<section
[formGroupName]="i"
*ngFor="let tech of form.controls.stations.controls; let i = index">
<ion-button
(click)="removeInputField(i)"
*ngIf="form.controls.technologies.length > 1"
class="ion-no-padding ion-float-right" shape="round" fill="clear">
<ion-icon slot="start" name="close"></ion-icon>Remove</ion-button>
</ion-item-group>
</section>
<div>
<!-- Allow new input field to be generated/added -->
<ion-button
(click)="addNewInputField()"
class="ion-no-padding ion-float-left" shape="round" fill="clear">
<ion-icon slot="start" name="add"></ion-icon> Add a new technology</ion-button>
</div>
.ts
@ViewChild('autoStation', {static: true}) autoStation: any;
ngAfterViewInit(): void {
this.autoCompleteStation.forEach( autoStation => {
autoStation.getInputElement().then(( input: HTMLInputElement) => {
var autocompl = new google.maps.places.Autocomplete(input, {
//somee code
});
}
});
addNewInputField() : void {
const control = this.form.controls.technologies as FormArray;
control.push(this.initTechnologyFields());
}
removeInputField(i : number) : void {
const control = this.form.controls.technologies as FormArray;
control.removeAt(i);
}
[![在此处输入图片描述][1]][1]
[![在此处输入图片描述][2]][2]
我添加了一些图片来大致了解这个问题,第一张图片是我制作的 UI 第二张是什么时候尝试输入城市 google 地方 api 正在工作,但是当我单击添加新城市的按钮时,生成了文本字段,但是 google 地方 api 不起作用,这就是问题所在。
这是我认为您的代码中发生的情况:
将 API 用于通过 *ngFor 创建的组件模板中已有的离子输入的原因很简单 - 在组件的 ngAfterViewInit 生命周期中,您有一个运行的方法在所有这些离子输入中,获取它们的原生输入元素并为它们中的每一个初始化 Places API。
当您使用按钮添加新的离子输入时 - 对于新添加到 DOM 输入的那些,没有任何东西可以帮助初始化位置 API。
要修复 #2,您需要确保 DOM 的此类新添加的离子输入得到初始化的位置 API。
如果您遵循我的回答,您的
...get the QueryList of elements or directives from the view DOM. Any time a child element is added, removed, or moved, the query list will be updated, and the changes observable of the query list will emit a new value.
如果是这样,则意味着您的代码中有:
@ViewChildren('autoStation') autoStationList:QueryList<any>;
每次您添加另一个带有#autostation 标识符的离子输入时,此 autoStationList 都会更新。
这意味着您只需获取此 QueryList 的最后一个子项并为其初始化 Places API。您可以使用 QueryList 的 changes() 方法来做到这一点,您可以订阅该方法,每次列表更改时 - 获取其 "last" 元素,提取输入并初始化位置 API:
ngAfterViewInit(): void {
// here you initialize all ion-input's native inputs that exist in DOM at component view initialization stage:
this.autoCompleteStation.forEach( autoStation => {
autoStation.getInputElement().then(( input: HTMLInputElement) => {
let autocompl = new google.maps.places.Autocomplete(input, {
//some code
})
});
// here you subscribe to changes for the list:
this.autoStationList.changes.subscribe(list => {
// here we need to use "last" property of the list:
list.last.getInputElement().then(( input: HTMLInputElement) => {
var autocompl = new google.maps.places.Autocomplete(input, {
//somee code
})
})
});
}