Angular 2 + SignalR - Accessing Angular internals

2019-06-02 07:52发布

问题:

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

回答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);