简体   繁体   中英

Angular 2 setting a new value does not trigger an input change event

I'm running into a weird case that only seems to happen upon first loading a component on a heavily based component page (loading 30+ components).

@Component{
    selector: <parent-component>
    template: `<child-component [myObject]=myObject>
}
export class ParentComponent { 
    private myObject:DTOValue;
    constructor(service:MyService){
        service.getDTOValue().subscribe((dtoValue:DTOValue) => {
            this.myObject = dtoValue;
        });
    }
}

@Component{
    selector: <child-component>
    template: `<div></div>
}
export class ChildComponent { 
    @Input set myObject(value:DTOValue) => {//do something};
    constructor(){
    }
}

In this code, the Parent is going to get a value to a child as an input. This value comes from a request at a later time, so when the child is first initialized, the input could be undefined. When the value does get returned from the request and is set on the variable myObject , I'd expect that the child component would receive an input event being triggered. However, due to the timing, it seems like this is not always the case, especially when I first load a page that contains a lot of files being loaded.

In the case that the child component doesn't receive the input, if I click else where on my page, it seems to now trigger the change detection and will get the input value.

The 2 possible solutions I can think of that would require some large code changes so I want to make sure I choose the right now before implement them.

  1. Change the input to be an Subject, so that I push the input value which should ensure that a correct event is triggered(this seems like overkill).

  2. Use the dynamic loader to load the component when the request as return with the correct value (also seems like overkill).

UPDATE: Adding a plnker: http://plnkr.co/edit/1bUelmPFjwPDjUBDC4vb , you can see in here that the title seems to never get its data bindings applied.

Any suggestions would be appreciated.

Thanks!

If you can identify where the problem is and appropriate lifecycle hook where you could solve it, you can let Angular know using ChangeDetectorRef .

constructor(private _ref: ChangeDetectorRef)

method_where_changes_are_overlooked() {
  do_something();
  // tell angular to force change detection
  this._ref.markForCheck();
}

I had a similar issue, only with router - it needed to do redirect when/if API server goes offline. I solved it by marking routerOnActivate() for check...

When you trigger change detection this way a "branch" of a component tree is marked for change detection, from this component to the app root. You can watch this talk by Victor Savkin about this subject...

Apologize, the issue ended up being my interaction with jQuery. When I triggered an event for a component to be loaded, inside of the jQuery code, it wouldn't trigger the life cycle. The fix was after the code was loaded to then call for a change detection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM