2014-01-30 2 views
1

У меня есть приложение, использующее @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

+1

Я подозреваю ошибку с js-interop. Чтобы проверить: введите NgZone в TestController, создав конструктор: «TestController (NgZone this._zone)», а затем вызовите _zone.assertInTurn() внутри _onConnect(). ---- Если это утверждение бросает, появляется ошибка; обход - обернуть _onConnect в _zone.run(). ---- Если утверждение не бросает, происходит что-то еще. –

+0

Я очень впечатлен Джеймсом. От какой звезды вы идете ?! ;-) –

+0

@JamesdeBoer Вы бы могли предложить вместо NgZone последнюю версию angular.dart (0.11.0)? Спасибо ;-) –

ответ

1

То, что вы описываете, должно работать вне - o е коробки. Единственная сложная часть касается списков: чтобы обнаружить изменения в списке, а пользовательские директивы должны использовать Scope.$watchCollection для просмотра коллекции. Обычные часы и карты атрибутов будут пропускать изменения в списке.

Встроенные директивы, которые касаются списков (например, ng-repeat) уже используют $watchCollection.

+0

Я использую список. Что вы считаете сложным: обнаруживаете изменения в объекте списка или в элементах списка? –

+0

Да, это сложно. Угловая должна решить вашу проблему. - Как выглядит ваше мнение? Вы используете ng-repeat для отображения списка или чего-то еще? –

+0

Чтобы ответить на ваш вопрос, я использую ng-repeat. Я попытался изолировать проблему, и похоже, что она имеет какое-то отношение к взаимодействию javascript, которое я использую для связи с фреймворком socket.io.Я обновляю вопрос с помощью фрагмента кода, который я использовал. –

Смежные вопросы