Использование наблюдаемых в Dart для обнаружения изменений Angular2

В моем приложении Angular2, написанном на Dart, есть несколько сервисов, которые отслеживают данные, совместно используемые компонентами, которые не обязательно имеют какое-либо конкретное отношение в представлении. Мне нужно, чтобы обновления, инициированные каким-либо компонентом, отражались на дисплее каждого компонента, я хочу, чтобы преимущества производительности OnPush обнаруживали изменения, мне нужно, чтобы компоненты отображали значения, которые могли быть установлены до того, как компонент был создан, и я хочу, чтобы все это было выполнено с минимальным шаблоном.

Мое исследование показывает, что Observables может быть тем, что мне нужно, но я не смог найти четких ответов по нескольким вопросам.

Есть ли реализация Observable в Dart, которая хорошо работает с Angular2?

Отличается ли Observable от Dart Stream? В частности, поддерживает ли Observable получение текущего значения в дополнение к уведомлению о будущих обновлениях?

И последнее, но не менее важное: если предположить, что Observable соответствует моим требованиям, то каким будет минимальный синтаксис для объявления свойства Observable String компонента, его инициализации с помощью Observable, полученного из внедренной службы, отображения его значения в шаблоне компонента (начиная с предварительного -существующее значение), и наличие обновлений его значения автоматически помечает компонент для обнаружения принудительных изменений?

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

Мое идеальное решение будет выглядеть примерно так:

@Injectable()
class MyService {
  @observable int health;
}

@Component(
    ...)
class MyComponent {
  @observable int health;
  MyComponent(MyService service) : health = service.health;
}

И в шаблоне:

<span>{{health | async}}</span>

Или для действительно идеального, хотя это должно было бы каким-то образом подключиться к компиляции шаблона Angular (может быть, с преобразователем? Я еще не узнал, как они работают):

<span>{{health}}</span>

И только с этим, это просто сработает.

Пользовательское решение, которое у меня сейчас работает, не так удобно, но близко к этому.


person Douglas    schedule 08.03.2016    source источник


Ответы (1)


Для коллекций и классов вы можете использовать https://pub.dartlang.org/packages/observe. Он специально не предназначен для использования с Angular2, скорее для Polymer ‹= 0.16.x, но он должен хорошо работать с Angular2 OnPush.

Если вы сделаете коллекцию наблюдаемой

List myList = toObservable([]);

вы можете подписаться на изменения

myList.changes.listen((record) {
  // invoke Angular change detection
});

Когда классы расширяют Observable (напрямую или путем применения миксина Observable)

class Monster extends Unit with Observable {
  @observable int health = 100;

  void damage(int amount) {
    print('$this takes $amount damage!');
    health -= amount;
  }

  toString() => 'Monster with $health hit points';
}

вы также можете подписаться на изменения и уведомить Angular

var obj = new Monster();
obj.changes.listen((records) {
  // invoke Angular change detection
});

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

Отличается ли Observable от Dart Stream? ...

Я думаю, что Dart Observable по смыслу отличается от Stream. someObservable.changes возвращает Stream, который генерирует изменения, но эти события изменения генерируются реализацией Observable и преобразователем, который генерирует дополнительный код из аннотаций @observable свойств.

В частности, поддерживает ли Observable получение текущего значения в дополнение к уведомлению о будущих обновлениях?

Когда вы привязываетесь к свойствам наблюдаемого, вы получаете текущее значение. Когда значения изменяются, и подписка changes уведомляет об этих изменениях, и вы уведомляете обнаружение изменений Angular о том, что изменения произошли, Angular обновит привязки до последних значений.

минимальный синтаксис для объявления свойства Observable String компонента,

В приведенном выше примере кода показано свойство int, но при использовании String разницы нет.

person Günter Zöchbauer    schedule 09.03.2016
comment
Если я правильно читаю документацию, мне нужно будет либо повторно опросить объект с помощью dirtyCheck(), либо реализовать ChangeNotifier с шаблоном в каждом сеттере, и в любом случае вручную подключить .changes.listen() каждого объекта к ChangeDetectorRef.markForCheck() Angular2. Это слишком много многократно повторяющегося кода для хорошего решения. Это ближе к тому, что мне нужно, чем что-либо еще, что я нашел, но похоже, что мне, возможно, придется сделать собственное решение. - person Douglas; 10.03.2016
comment
Это звучит правильно. Прошло некоторое время с тех пор, как я использовал его сам. - person Günter Zöchbauer; 10.03.2016
comment
Можете ли вы расширить // вызов обнаружения изменений Angular - person Warren Strange; 08.05.2017
comment
Обнаружение изменений — обширная тема. stackoverflow.com/questions/34827334/triggering может помочь - person Günter Zöchbauer; 08.05.2017