Веб-интерфейс Dart не обновляется при получении данных из сети

У меня есть следующий фрагмент в веб-компоненте:

<div id="mycodes">                     
<template iterate='code in codeList'>
   {{code}}
</template>  
</div> 

А в файле Dart codeList заполняется, когда пользователь нажимает кнопку:

void onMyButtonClick(Event  event) {
  HttpRequest.getString('http://getData').then((response) {
  mylist = json.parse(response);
  for(var code  in mylist){
    codeList.add(code['c']);
  }
}

Проблема в том, что я не вижу данные при первом нажатии. Мне нужно дважды нажать кнопку, чтобы увидеть данные.

Но если я заполню codeList вручную (не из сетевых данных), как показано ниже, то я увижу данные при первом нажатии:

void onMyButtonClick(Event  event) {

    codeList.add("data 1");
    codeList.add("data 2");
  }
}

Мне нужно, чтобы шаблон повторялся после того, как сетевые данные станут доступны. Похоже, что цикл событий уже выполнил свою работу по рисованию страницы до того, как сетевые данные станут доступны через будущий объект. Есть ли способ обновить страницу после обновления модели в дротике?


person Tusshu    schedule 29.05.2013    source источник
comment
Можете ли вы показать нам объявление codeList?   -  person ianmjones    schedule 29.05.2013
comment
вы уверены, что первый запрос к 'http://getData' возвращает то, что вы ожидаете?   -  person Zdeslav Vojkovic    schedule 30.05.2013


Ответы (2)


Причина, по которой ваш список кодов в настоящее время заполняется, если вы добавляете его с событием по клику, заключается в том, что текущий web_ui имеет «наблюдателей», которые автоматически вызываются, когда происходит событие. Затем вы заполняете список синхронно. Однако одним из недостатков наблюдателей является именно ваш вариант использования, когда данные обновляются асинхронно, тогда наблюдатели не отражают изменения во времени.

В результате наблюдатели постепенно упраздняются и заменяются наблюдаемыми. Наблюдаемые объекты позволяют нам пометить переменную для наблюдения за переназначением, и когда это произойдет, это приведет к изменению представления. Например:

@observable int x = 0;
// ...
x = 1;

Когда x = 1 вызывается позже в коде, он автоматически запускает обновление представлений. Однако это оставляет нам одну проблему. Когда вы добавляете в список, вы не переназначаете само значение. Таким образом, наблюдаемые также предлагают функцию преобразования списка в наблюдаемый список (это также работает для карт).

Например, если вы изменили свое объявление codeList на что-то вроде следующего, то когда вы добавите в список позже, он будет соответствующим образом обновлен.

var codeList = toObservable([]); // Assuming it starts with an empty list
// or
var codeList = toObservable(_startCodeList); // if you already have a list

Также см. Учебное пособие по Dart: Target 7, чтобы узнать больше. информация об использовании @observable и toObservable. Более подробную информацию можно найти в статье Observables and Data Binding.

person Matt B    schedule 30.05.2013

Вам нужно пометить поля, которые WebUi должен отслеживать, аннотацией @observable. В противном случае вы получите только начальное значение, а не последующие обновления.

Вы можете сделать это либо непосредственно в объявлении объекта, либо вы можете сделать весь класс наблюдаемым, и тогда все его поля будут наблюдаться.

Пример см. на http://www.dartlang.org/docs/tutorials/custom-elements/#using-two-way-data-binding

person Charlie M    schedule 30.05.2013