-1

I'm trying to combine Angular2 with jQuery + Chosen plugin. It's basically an extension of the answer to this question How to use jQuery with Angular2?.

I want to dynamically update items displayed in Chosen select box. Chosen has chosen:updated event design for this but I need to trigger it after component's view has been updated because Chosen just looks at the <option> elements and generates its content based on them.

You can see live "working" demo: http://plnkr.co/edit/42RaphKFHPNrNYuWlrbe?p=preview

This means that if I do:

this.items.push('Another #' + this.items.length);
jQuery(this.el.nativeElement).find('select').trigger("chosen:updated");

It won't do anything because the view hasn't been updated after calling this.items.push().

I tried wrapping trigger("chosen:updated") with setTimeout to call it asynchronously which I thought could help.

this.items.push('Another #' + this.items.length);
setTimeout(() => {
    jQuery(this.el.nativeElement).find('select').trigger("chosen:updated");
});

It seems like it does help but I'm wondering if this is the correct approach or just coincidence that this works?
I thought there could be some event on components called after their view has been updated but it seem like none of them do what I need.

Edit: The same problem is very well described in another question: Triggering Angular2 change detection manually.

Updated working demo: http://plnkr.co/edit/w7hHmUaD9Eqq3ffQueXp?p=preview

Community
  • 1
  • 1
martin
  • 93,354
  • 25
  • 191
  • 226

1 Answers1

1

this.items.push(...) seems to be invoked by code that runs outside Angulars zone. Angular runs within a zone and within that zone most async APIs are patched (events, setTimeout, ...) to notify Angular about necessary change detection.

If code runs outside that zone, Angular doesn't get notified about finished async execution and change detection doesn't happen. If you run code within setTimeout(...) change detection is run when the call is completed.

See Triggering Angular2 change detection manually for other ways to make Angular run change detection.

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • I think `this.items.push()` runs inside a zone because it's invoked by `(click)` event. I've tried using `NgZone` before but my use-case is different, I need to call a function after change detection. – martin Mar 10 '16 at 12:33
  • The answer you linked is exactly what I was looking for: http://stackoverflow.com/questions/34827334/triggering-angular2-change-detection-manually – martin Mar 10 '16 at 12:34