在angular2组件中更改div的[hidden]标志后,视图不会更新

时间:2016-12-05 10:38:07

标签: angular google-maps-api-3 typescript

我有一个自定义组件,其定义如下:

    import { Component, NgModule, OnInit, ViewChild, ElementRef, Input, Output, EventEmitter } from '@angular/core';
    import { FormControl, FormsModule, ReactiveFormsModule } from "@angular/forms";
    import { AgmCoreModule, MapsAPILoader } from 'angular2-google-maps/core';
    import { GoogleLocation } from '../../domain/data/general/googlelocation'

        @Component({
            selector: 'syx-googlemapsplacesautocomplete',
            providers: [],
            styles: [],
            template: `<input name='{{name}}' 
                              id='{{id}}' 
                              class='input' 
                              placeholder="{{placeholderText}}" 
                              autocorrect="off" 
                              autocapitalize="off" 
                              spellcheck="off" 
                              type="text"
                              (keyup.enter)="emitEntered()"
                              #search>`
        })


        export class GoogleMapsPlacesAutocomplete implements OnInit {

            private searchControl: FormControl;
            private googleLocation: GoogleLocation = new GoogleLocation();

            @Input() public placeholderText: string;
            @Input() public id: string;
            @Input() public name: string;

            @Output() notify: EventEmitter<GoogleLocation> = new EventEmitter<GoogleLocation>();
            @Output() entered:EventEmitter<string> = new EventEmitter<string>();
            @ViewChild("search")
            public searchElementRef: ElementRef;

            constructor(private mapsAPILoader: MapsAPILoader) {
            }

            emitEntered() {
                this.entered.emit('complete');
            }

            ngOnInit() {
                //create search FormControl
                this.searchControl = new FormControl();

                //load Places Autocomplete
                this.mapsAPILoader.load().then(() => {
                    let autocomplete = new google.maps.places.Autocomplete(this.searchElementRef.nativeElement, {
                        types: ["(cities)"] // only renders cities of world. (Does not render street, area, any business etc.)
                    });

                    autocomplete.addListener("place_changed", () => {
                        try {
                            //get the place result
                            let place: google.maps.places.PlaceResult = autocomplete.getPlace();
                            this.googleLocation = new GoogleLocation();
                            var oParser = new DOMParser();
                            var oDOM = oParser.parseFromString(place.adr_address, "text/html");
                            this.googleLocation.Address = oDOM.getElementsByTagName("body")[0].firstChild.textContent;
                            this.googleLocation.StreetAddress = oDOM.getElementsByClassName("street-address")[0].innerHTML;
                            this.googleLocation.Locality = oDOM.getElementsByClassName("locality")[0].innerHTML;
                            this.googleLocation.Country = oDOM.getElementsByClassName("region")[0].innerHTML;
                            this.googleLocation.PostalCode = oDOM.getElementsByClassName("postal-code")[0].innerHTML;
                            this.googleLocation.CountryName = oDOM.getElementsByClassName("country-name")[0].innerHTML;
                        }
                        catch (error) {
                        } finally {
                            this.notify.emit(this.googleLocation);
                        }
                    });
                });


            }

            resetInput(){
                this.searchElementRef.nativeElement.value = "";
            }
        }

我的数据模型类如下:

export class GoogleLocation {
    public Address: string;

    public StreetAddress: string;

    public Locality: string;

    public Region: string;

    public PostalCode: string;

    public CountryName: string;
}

我的主要页面组件是:

@Component({
    selector: 'aa-register',
    styles: [],
    templateUrl:  "someTemplate"
})

export class RegisterComponent {
    public googleLocation: GoogleLocation = new GoogleLocation();

    private showGoogleLocation : boolean;  

    private city : string;
    private state : string;
    private country : string;
    private postalcode : string;

    private onNotify(googleLocation: GoogleLocation) {
        this.googleLocation = googleLocation;
        this.city = this.googleLocation.Locality;
        this.state = this.googleLocation.Region;
        this.country = this.googleLocation.CountryName;
        this.postalcode = this.googleLocation.PostalCode;
        this.HideGoogleLocation(); 
    }

    constructor() {
        this._mapTextBoxPlaceHolderText = "e.g. Brussels";
        this.showGoogleLocation = true;
    }

    HideGoogleLocation() : void
    {
        this.showGoogleLocation = false;
    }

    ShowGoogleLocation() : void
    {
        this.showGoogleLocation = true;
        this.googleLocation = new GoogleLocation();
        this.city = this.googleLocation.Locality;
        this.state = this.googleLocation.Region;
        this.country = this.googleLocation.CountryName;
        this.postalcode = this.googleLocation.PostalCode;
    }
}

html的使用是:

    <form #myForm="ngForm">
        <label for="txtCity" class="font14-roboto-black">CITY NAME</label>            
        <div id="google_location" [hidden]="!showGoogleLocation">
            <syx-googlemapsplacesautocomplete 
                id="txtCity" name="txtCity" 
                [(ngModel)]="googleLocation" 
                required 
                #txtCity
                [placeholderText]="_mapTextBoxPlaceHolderText"
                (notify)="onNotify($event)"
                ngDefaultControl>
            </syx-googlemapsplacesautocomplete>            
            <br />        
            <a (click)="HideGoogleLocation()">Enter Address</a>
        </div>
        <div id="create_location_content" [hidden]="showGoogleLocation">
           <input name=txtCityLocation #txtCityLocation="ngModel" id=txtCityLocation name=txtCityLocation type="text" [(ngModel)]="city" >               
           <label for="txtState">STATE</label>               
           <input name=txtState #txtState="ngModel" id=txtState name=txtState type="text" [(ngModel)]="state" >
           <label for="txtCountry">COUNTRY</label>               
           <input name=txtCountry #txtCountry="ngModel" id=txtCountry name=txtCountry type="text"  [(ngModel)]="country" >     
           <label for="txtPostalCode">POSTAL CODE</label>               
           <input name=txtPostalCode #txtPostalCode="ngModel" id=txtPostalCode name=txtPostalCode type="text"  [(ngModel)]="postalcode" >               
           <br />
            <a (click)="txtCity.resetInput(); ShowGoogleLocation();">Reset Location</a>
        </div>

        <div>
            <button class="button-primary" type="button" (click)="register($event)" name="btnReady" [disabled]="!myForm.valid">
            Ready</button>
            <br/>
        </div>
    </form>

标志已更改,但div可见性更改仅在我点击“txtCity&#39;或按回车。

我希望用户在某个地方输入内容: 例如类型Mumb 并选择&#34;孟买,马哈拉施特拉邦,印度&#34;从地方列表 并在同一时刻div&#34; google_location&#34;隐藏和地点在其他div中自动填充,即&#34; create_location_content&#34;文本框和其他div变得可见。

1 个答案:

答案 0 :(得分:0)

我假设涉及一些调用ShowGoogleLocation的外部API,导致更改检测无法识别它必须运行。

明确地运行它应解决问题:

constructor(private cdRef:ChangeDetectorRef) {

...

ShowGoogleLocation() : void
{
    this.showGoogleLocation = true;
    this.googleLocation = new GoogleLocation();
    this.city = this.googleLocation.Locality;
    this.state = this.googleLocation.Region;
    this.country = this.googleLocation.CountryName;
    this.postalcode = this.googleLocation.PostalCode;

    this.cdRef.detectChanges();
}