3

I have an Angular 2 app that builds a tree using mermaidJS, which is a JS (not TS) framework.

To bind clicks on this tree to Angular events, in my ngOnInit() method I create window functions, like this :

window['myFunctionToBeCalledFromTheTree'] = () => { ...}

It all works great.

The problem that occurs, is that once any of those functions is called, Angular doesn't detect changes anymore. I have found a quick workaround with the change detector, but I have to call it everytime.

My questoin is, is there a way to give back its automatic change detection to Angular ?

Maciej Treder
  • 11,866
  • 5
  • 51
  • 74
  • 2
    try injecting `NgZone`in `constructor(zone: NgZone)` and wrapping your functions with `window['myFunctionToBeCalledFromTheTree'] = () => { this.zone.run(() => { ... } }` – Max Koretskyi May 23 '17 at 10:18
  • @Maximus I don't know if this is necessary - `NgZone.run` [is meant to be run inside](https://stacksandfoundations.com/2016/10/04/understanding-ngzone/) `NgZone.runOutsideAngular` - I think most code will automatically be run inside a zone, even raw JS code. – Daniel Cooke May 23 '17 at 10:58
  • @DanielCooke Then what would you do ? –  May 23 '17 at 12:43
  • Inject `ChangeDetectorRef` and call `changeRef.detectChanges` manually. https://stackoverflow.com/questions/34827334/triggering-angular2-change-detection-manually -- if that doesn't work call `.markForCheck()` – Daniel Cooke May 23 '17 at 12:45
  • @DanielCooke I already did that, the problem is that you have to call it at every method call or every variable change. I would like to have the automatic detection, like it is when you don't exit the Angular context. –  May 23 '17 at 12:57
  • @trichetriche normally you should include what you have tried in your question - anyway. Try zone.run() then. I was merely pointing out that you shouldn't have to, it will work if your code is being processed outside of angular. – Daniel Cooke May 23 '17 at 12:59
  • @DanielCooke quote : `I have found a quick workaround with the change detector, but I have to call it everytime`. Ok I will try Maximus's way, thank you both –  May 23 '17 at 13:01
  • @trichetriche, try my way and let me know – Max Koretskyi May 23 '17 at 13:04
  • @DanielCooke, _I think most code will automatically be run inside a zone_, not the code that started outside angular zone, like the one triggered by `mermaidJS` – Max Koretskyi May 23 '17 at 13:05
  • @Maximus WHAT. THE .HECK. I spent literally 2 weeks trying to solve that with the `changeDetector`, and your only line of code made it work. If people wonder how it works, see [the documentation](https://angular.io/docs/ts/latest/api/core/index/NgZone-class.html) –  May 23 '17 at 13:19
  • Please @Maximus, post an answer so I can mark it as resolved, you deserve the reputation. –  May 23 '17 at 13:20

1 Answers1

2

The problem is that the code in your callback runs outside Angular zone. You need to run it inside Angular zone:

window['myFunctionToBeCalledFromTheTree'] = () => { this.zone.run(() => { ... } }

You can't use change detector here because the changes made during change detection will not be picked by next change detection loop.

Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488