1

I'm using SignalR with an Angular2 app, where we want the SignalR client methods to call into the Angular app with data received from the server, and then have Angular redo the data-bindings. For example, within the Angular app I expose a global variable for our store, which has a collection on it.

E.g. (TypeScript)

....
export class Store{
  Customers : Customer[];
  constructor(){
    window["GlobalStore"] = this;
  }

  setCustomers (customers : Customer[]){
    this.Customers = customers;
  }
}
....

and in my client SignalR javascript I have a function:

$.connection.MyHub.client.receive = function(data){
  //Call into the Angular app and set data, which is then rendered in views
  //via data-binding
  //data contains a json array of customers
  window.GlobalStore.setCustomers(data);
}

This seems to work and set the data on the store, however, when the data is reset Angular does not seem to detect changes, and hence the UI is not refreshed.

It's not an issue with data-typing, as even passing a simple string/integer etc through to the store correctly sets the store property when I debug, however, the Angular framework doesn't seem to then trigger change detection and refresh the views.

Any ideas on how to either: A) Manually trigger the angular databinding so it refreshes the view? B) Call methods within the Angular 2 app from external using a different means?

Thanks

DilumN
  • 2,889
  • 6
  • 30
  • 44
Phil Lee
  • 92
  • 2
  • 7

1 Answers1

1

To manually run change detection:

  1. Use ApplicationRef::tick() method.
  2. Use NgZone::run() method to wrap you code which should be executed inside angular zone.

You can get them by using dependency injection or by bootstrapping your application using platform().application(bindings).bootstrap(Component):

import { platform } from 'angular2/angular2';

const app = platform().application([] /* - bindings */); // you can use `app.tick()` 
const zone = app.zone; // you can use `zone.run`

app.bootstrap(Component);
alexpods
  • 47,475
  • 10
  • 100
  • 94
  • Thanks @alexpods. Has the .tick() method only been added in alpha 46? I'm trying to find in 45 but had no luck... In the event I move to 46, could I then have a component which is as follows: export class MyClass{ constructor(private applicationRef: ApplicationRef){ } makeItTick(){ this.applicationRef.tick(); } } – Phil Lee Nov 26 '15 at 00:33
  • 1
    Before alpha 46 there was `LifeCycle::tick()` method with the same purpose. See [this SO answer](http://stackoverflow.com/questions/33174146/angular-2-0-equivalent-to-scope-apply/33175487#33175487). The `LifeCycle` was removed in alpha 46. – alexpods Nov 26 '15 at 16:41
  • Yes, you can inject `applicationRef` and then use its `tick` method. I think, the code you've written will work. – alexpods Nov 26 '15 at 16:48
  • 1
    Note you can run change detection on the current component using the `detectChanges()` method of the `ChangeDetectorRef` object imported from `angular2/core` ([Plunker](http://plnkr.co/edit/mSnsKXUCoxPqrmr3wpHz?p=preview)). The tick approach triggers change detection for the entire application. – Kiara Grouwstra Feb 06 '16 at 16:00