0
votes

I have an ng2 component with the following class definition:

import { Component, OnInit, OnChanges, SimpleChanges, Input, NgZone } from '@angular/core';
import { Router } from '@angular/router';
import { SearchService } from '../../services/search.service';

@Component({
    selector: 'search',
    templateUrl: '../../../ng2/templates/search.component.html'
})

export class SearchComponent implements OnInit, OnChanges
{
    @Input() searchMetadata;

    constructor(
        private router: Router,
        private searchService: SearchService,
        public ngZone: NgZone)
    {
    }

    ngOnInit()
    {
        this.getSearchMetadata();
    }

    ngOnChanges(changes: SimpleChanges)
    {
        alert('ngOnChanges entered');
    }

    getSearchMetadata()
    {
        this.searchService
            .getSearchMetadata()
            .then(this.processSearchMetadata.bind(this))
            .then(this.validateVariableSet.bind(this))
            .then(responseObject => this.blogSearchMetadata = "TEST");
    }

    processSearchMetadata(responseObject)
    {
        this.searchMetadata = Object.assign(new SearchMetadata(), responseObject)
    }

    validateVariableSet()
    {
        alert(this.searchMetadata);
    }
}

The final validateVariableSet() function validates that the member variable gets set as expected. It successfully alerts the value. However, ngOnChanges() does not get hit. My understanding was that any variable marked with @Input() would trigger the ngOnChanges event after that variable's value changed. Any idea what the gap might be here?

UPDATE 1

Here's a simple template html. My goal is just to get a handle to ddlTest but I can't do this until the *ngIf (searchMetadata) has been realized. Based on some previous research, using the ngOnChanges() hook seemed like the best way to do this but I'm open to suggestions for a more appropriate solution

<router-outlet>
    [{{searchMetadata}}]
    <div *ngIf="searchMetadata">
         <select id="ddlTest">
             <option>1</option>
             <option>2</option>
             <option>3</option>
    </select>
    </div>
 </router-outlet>

UPDATE 2

The following approach works. It's simple and straight forward. It's hacky but it works. When addJQueryHook() gets hit, ddlTest above will already be rendered. If you know a better way then please lmk!

<div *ngIf="SearchMetadata">
    <select id="ddlTest">
        <option>1</option>
        <option>2</option>
        <option>3</option>
    </select>
    <div *ngIf="addJQueryHook()">
    </div>
</div>
1
ng actually gets hit twice: first time before ngOnIjit and then afterwards for each change in @Input variables. i would check data binding process if i were you. can you show how you actually bind your variable? - dee zg
thanks dee. I'm binding to the variable in my html template like this: {{searchMetadata}}. I'm binding to the variable in a few different parts of the template for test purposes. - user8334943
I also added a line to my code in my original post to explicitly bind the variable to 1 value and then explicitly bind the variable to another value. This binding gets reflected in my html but the ngOnChanges() event does not get triggered - user8334943
i am a bit confused. where is your {{searchMetadata}} expression located? in the template of this component or in the template of the component that uses/instantiates this component? - dee zg
@dee - I included some additional code in my original post. The expression is located in search.component.html - user8334943

1 Answers

0
votes

Ok, comments are too small to give answer.

The way this binding and ngOnChanges work is like this...

You have some component, lets call it ContainerComponent. In template of that one, you, for example, use your search component like this:

<search [searchMetadata]="somePropertyOnYourContainerComponent">

this will bind your search components @Input() searchMetadata to somePropertyOnYourContainerComponent and your ngOnChanges will trigger.