I have an app using @NgController
and the working use case where an UI action triggers a change in the model, which immediately get reflected in the view. The model consists of a list of objects.
What is not working is when the triggered action is starting some asynchron process which eventually modifies the model (adds new elements in the list). The view gets no update.
I guess this works as designed and I am missing something. What pattern should I use in this case?
UPDATE: Here the minimal code snippet showing the problem:
<html ng-app>
<head>
<meta charset="utf-8">
<title>Angular bug test</title>
<link rel="stylesheet" href="angular_bug_test.css">
<script src="http://lounge-server.jit.su/socket.io/socket.io.js"></script>
</head>
<body test>
<h1>Angular bug test</h1>
<p>The number of element in the list is {{controller.list.length}}</p>
<input ng-click="controller.addElementSync()" type="button" value="Add Sync"></input>
<input ng-click="controller.addElementAsync()" type="button" value="Add Async"></input>
<input ng-click="controller.addElementJsAsync()" type="button" value="Add JS Async"></input>
<ul>
<li ng-repeat="element in controller.list">{{element}}</li>
</ul>
<script type="application/dart" src="angular_bug_test.dart"></script>
<script src="packages/browser/dart.js"></script>
</body>
</html>
and the corresponding dart code:
@NgController(selector: '[test]', publishAs: 'controller')
class TestController {
List<String> list = new List<String>();
void addElementSync() {
list.add("${list.length}. element");
}
void addElementAsync() {
new Timer(new Duration(seconds: 1), () => list.add("${list.length}. element"));
}
void addElementJsAsync() {
context['io']
.callMethod('connect', ['http://lounge-server.jit.su:80/'])
.callMethod('on', ['connect', _onConnect]);
}
void _onConnect() {
Logger.root.fine('connected');
list.add("${list.length}. connected");
Logger.root.fine('list.length = ${list.length}');
}
}
When triggering the Add JS Async
button the console shows the following:
FINE : connected
FINE : list.length = 6
Unfortunately, neither the ng-repeat
nor the {{controller.list.length}}
gets updated.
UPDATE: The following workaround fix this problem in JS interop (kudos to James)
NgZone _zone; TestController(NgZone this._zone); void addElementJsAsync2() { context['io'] .callMethod('connect', ['http://lounge-server.jit.su:80/']) .callMethod('on', ['connect', _zone.run(_onConnect)]); }
UPDATE: The bug is still present in 0.11.0 and NgZone
has been renamed VmTurnZone