【问题标题】:Why will a google maps API component work without *NgIf but works if excluded? Angular 9为什么 google maps API 组件在没有 *NgIf 的情况下可以工作,但如果排除在外则可以工作?角 9
【发布时间】:2020-03-20 23:49:42
【问题描述】:

我尝试按照thread 中列出的步骤进行操作。它可以使用此组件加载搜索框:

map.component.html

<input id= 'box2'  *ngIf="boxReady" class="controls" type="text" placeholder="Search Box">
<input id = 'box' class="controls" type="text" placeholder="Search Box">

map.component.ts

import {Component, Input, OnInit} from '@angular/core';
import {GoogleAPIService} from '../google-api.service';
declare var google: any;
@Component({
  selector: 'app-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.scss'],
})
export class MapComponent implements OnInit {
  @Input() boxIdVar: string;
  // @Input() id: string;
  boxReady = false;

  constructor(private _google: GoogleAPIService){}

  ngOnInit(): void {
    if (typeof google !== 'undefined') {
      console.log(google);
      console.log('Map.NgInit');
      console.log(this.boxIdVar);
      this.boxReady = true;
      let input = document.getElementById('box');
      let originSearch = new google.maps.places.SearchBox(input);
      input = document.getElementById('box2');
      let dest = new google.maps.places.SearchBox(input);
    }
    else {
      console.log('Google was undefined Map');
    }
  }
}

但是,如果我添加一个 *NgIf 语句,该语句将仅在加载组件时加载其中一个框,那么该搜索框将不再工作,并且我得到一个未捕获的 promise 异常。

map.component.html

<input id= 'box2'  *ngIf="boxReady" class="controls" type="text" placeholder="Search Box">
<input id = 'box' class="controls" type="text" placeholder="Search Box">

在控制台中发现错误:

ERROR Error: "Uncaught (in promise): TypeError: b is null
v$.prototype.o@https://maps.googleapis.com/maps-api-v3/api/js/40/5/places_impl.js:78:66

这一切都是因为我想动态改变输入框的Id。但它接缝的是,每当一个 HTML 元素有一些角度绑定变量时,功能就会中断。

【问题讨论】:

  • 我正在寻找一个名为 'b' TypeError: b is null 的变量,是否缺少某些代码?

标签: javascript angular typescript google-maps-api-3 angular-ng-if


【解决方案1】:

您正在查询ngOnInit() 中的DOM。对于 Angular 来说,这在组件生命周期中还为时过早,无法将其添加到 DOM 中。将 *ngIf 条件设置为 true 不会立即将其添加到 DOM。

相反,您应该在组件生命周期的后期运行任何需要 DOM 元素的代码,在 ngAfterViewInit() 中。

此外,获取 DOM 元素的更“Angular”方式是使用@ViewChild()

<input *ngIf="boxReady" #box2 />
@ViewChild('box2') box2: ElementRef;

boxReady = false;

ngOnInit(): void {    
  this.boxReady = true;    

  const viewChild = this.box2 ? this.box2.nativeElement : null;
  console.log('ngOnInit viewChild', viewChild); // null
}

ngAfterViewInit() {  
  const viewChild = this.box2.nativeElement;
  console.log('ngAfterViewInit viewChild', viewChild);
}

演示:https://stackblitz.com/edit/angular-2um7rp

【讨论】:

    猜你喜欢
    • 2016-01-30
    • 2016-11-27
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 2019-01-14
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多