У меня есть приложение, использующее @NgController
и рабочий прецедент, когда действие пользовательского интерфейса вызывает изменение модели, которое сразу же отражается в представлении. Модель состоит из списка объектов.Есть ли способ в угловом дроте, чтобы явным образом уведомить мнение о модифицированной модели?
Что не работает, когда инициированное действие запускает какой-то асинхронный процесс, который в конечном итоге модифицирует модель (добавляет новые элементы в список). Представление не обновляется.
Я предполагаю, что это работает так, как было разработано, и я что-то упускаю. Какую модель следует использовать в этом случае?
UPDATE: Здесь минимальный фрагмент кода, показывающий эту проблему:
<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>
и соответствующий код дротика:
@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}');
}
}
При срабатывании кнопки Add JS Async
консоль показывает следующее :
FINE : connected
FINE : list.length = 6
К сожалению, ни ng-repeat
, ни {{controller.list.length}}
не обновляется.
UPDATE: Следующий обходной путь исправить эту проблему в JS Interop (престижность Иакову)
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: Исправлена ошибка по-прежнему присутствует в 0.11.0 и NgZone
был переименован VmTurnZone
Я подозреваю ошибку с js-interop. Чтобы проверить: введите NgZone в TestController, создав конструктор: «TestController (NgZone this._zone)», а затем вызовите _zone.assertInTurn() внутри _onConnect(). ---- Если это утверждение бросает, появляется ошибка; обход - обернуть _onConnect в _zone.run(). ---- Если утверждение не бросает, происходит что-то еще. –
Я очень впечатлен Джеймсом. От какой звезды вы идете ?! ;-) –
@JamesdeBoer Вы бы могли предложить вместо NgZone последнюю версию angular.dart (0.11.0)? Спасибо ;-) –