Reputation: 3753
I've got an AngularDart application that is working, but I feel like I'm doing it wrong...
The application shows a list of events as they are received. The events get to the app via SignalR, but I don't think that's really relevant - the issue is the way I'm having to update the component's state in order to see the changes in the state get displayed on the page.
Here is a cut down version of my component:
@Component( selector: 'liveEvents', templateUrl: 'live_events.html', useShadowDom: false )
class LiveEvents implements ScopeAware {
VmTurnZone _vmTurnZone;
EventReceiver _eventReceiver;
LiveEvents( this._vmTurnZone, this._eventReceiver );
List<Event> events = new List<Event>();
void _onEventReceived(Event event) {
//TODO: This just does not seem right...
_vmTurnZone.run(() => events.add(event));
}
void set scope(Scope scope) {
var _events = _eventReceiver.subscribeToAllEvents( "localhost", _onEventReceived );
}
}
The EventReceiver
class is responsible for connecting to a SignalR server, receiving messages from that server and converting them into Event objects, and then calling whatever function was specified in the subscribeToAllEvents
(in this case, _onEventReceived
)
The angular template html is very simple:
<ul>
<li ng-repeat="event in events">Event: {{event.Id}}</li>
</ul>
This all works fine, but the bit I don't like is having to inject a VmTurnZone
object into the component, and to have to update the events property from within a call to run
on that VmTurnZone
. It just seems a bit overly complicated to me. But if I DON'T do it in the VmTurnZone.run
method, when the events property gets updated, the view is not updated to reflect that change. Only from within VmTurnZone.run
does it work.
Is there a simpler way to do what I'm after here? I've looked at adding a watch to the scope, but that didn't seem to work (and looks to me like it should be used for changes that happen the other way around - ie, the view updates the scope, and you want to do something when that happens).
Can any AngularDart experts let me know if there's a better way to do what I'm after?
Upvotes: 2
Views: 323
Reputation: 2247
https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:async.Stream
You could add your events to stream and then listen for these and signalr will see these changes, for example:
@Component( selector: 'liveEvents', templateUrl: 'live_events.html', useShadowDom: false )
class LiveEvents implements ScopeAware {
EventReceiver _eventReceiver;
LiveEvents( this._eventReceiver );
List<Event> events = new List<Event>();
void set scope(Scope scope) {
subscribe().listen((event){
events.add(event);
});
}
Stream<Event> subscribe(){
var streamController = new StreamController<Event>();
_eventReceiver.subscribeToAllEvents( "localhost", (event){
streamController.add(event);
});
return streamController.stream;
}
}
Upvotes: 1
Reputation: 657466
As far as I know this is necessary when the source of the change is outside of the default Angular zone (for example some JavaScript library) for Angular to recognize model changes.
Upvotes: 0