Я создал вещь с помощью NativeScript - Часть 2

Приключения в обнаружении изменений

Это вторая часть из трех частей. В Части 1 я даю свою точку зрения на NativeScript в качестве решения. Здесь я рассмотрю свои проблемы с обнаружением изменений с помощью Angular + NativeScript. Наконец, в Части 3 я говорю о том, как интегрировать рабочий процесс OAuth в ваше приложение NativeScript.

Состояние приложения и обнаружение изменений

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

Вы помните тот доморощенный сервер для синхронизации данных, о котором я упоминал ранее? Это причина моего блаженного ошибочного предположения. Способ передачи данных (если мы используем терминологию графов) - сериализация каждого узла вместе с его ребрами. Это означает, что если A имеет отношение «один ко многим» с B, экземпляр A будет сериализован следующим образом:

{
 “ID”: 1,
 “name”: “Aaaaamy”,
 “allMyBs”: [1,5,57,47,92,3,24]
}

и B нравится

{
 “ID”: 1
 “name”: “Beeeeeetle”,
 “myA”: 1
}

Поскольку у меня была вся необходимая информация с сообщением КАЖДОГО, которое я получил от сервера, я мог создать и поддерживать полный граф объекта в памяти и просто обновлять его свойства, когда приходили изменения. в. Тогда пользовательский интерфейс соответствующим образом обновился, и все было бы красиво, и мы все хихикали и уезжали на единорогах в закат. Нет.

Я реализовал весь коммуникационный интерфейс, локальное кеширование, сериализацию, отложенную загрузку и все остальное, прежде чем я попытался отобразить его в <ListView>, когда мой мир рухнул. Всевозможный ад налетел на проигрыш. Иногда приложение вылетало, иногда ListView часть экрана просто гасла. Иногда происходит только частичное отображение данных. И это было все, даже не пытаясь взаимодействовать с ним (прокручивать, выбирать, смахивать и т. Д.). Если бы я попробовал что-либо из этого, приложение неизменно вылетало из строя.

Я перепробовал все, что описано в книге, чтобы заставить его работать правильно. Я даже подключился к нативной стороне вещей в iOS, чтобы обновлять список через медленный интервал. Ничего не работало полностью.

На тот момент я серьезно сомневался в своих навыках как разработчика и полностью обвинял NativeScript и Angular во всех своих проблемах. Итак, поскольку у меня больше не было идей, я сделал перерыв в программировании на пару дней, чтобы подумать и исследовать.

Во время этого размышления я взглянул на то, как другие библиотеки (которые делали аналогичные вещи в реальном времени) структурировали свои API. В частности, я посмотрел на AngularFire. И везде я замечал закономерность. Если изменение было отправлено с сервера, это был весь график… каждый раз. Поэтому я изучил, как работает обнаружение изменений, и начал думать о том, насколько безумно было бы пытаться в общем случае обнаруживать изменения во всем графе объекта без инструментов. Итак, я немного подумал и спроектировал и пришел к тому, что я считаю довольно красивым решением.

Я бы реструктурировал свой локальный кеш и клиентские API, чтобы при запросе данных приложением оно получало Observable, а не простой объект. и всякий раз, когда в этой сущности или ЛЮБОЙ ЧАСТИ ЕГО ПОДГРАФА происходило изменение, наблюдаемый объект запускался с совершенно новым объектом (с точки зрения памяти, значения могут быть точно такими же) и последующим подграфом. Мне потребовалась пара дней, чтобы разобраться со всеми проблемами, но как только я это сделал, я полностью контролировал состояние своего приложения и его стратегию обнаружения изменений.

Теперь, когда я вставляю ListView в пользовательский интерфейс, он работает. Работает красиво. Он загружает только ту часть графика, которая необходима для отображения частей списка, отображаемых на экране. Когда я прокручиваю, он загружает новые части с сервера. Довольно весело наблюдать за потоком данных и заполнением пользовательского интерфейса.

Наряду с тем, что он фактически совместим с Angular и NativeScript, мой новый подход принес кучу других интересных побочных эффектов:

  1. Точно настройте рендеринг пользовательского интерфейса, ограничив скорость Observable. Поскольку теперь у меня есть поток данных, а не только момент времени, я знаю, когда произошло изменение, и забочусь ли я об этом или нет. В частности, я знал, что последнее изменение, которое я получил, было единственным, о котором я заботился, поэтому я мог ограничить срабатывание Observable только каждые 250 мс, потому что мне не нужно было рендерить чаще, чем это. (рендеринг при каждом обновлении приводил к сбою представления списка).
  2. Удалите другие ненужные обновления пользовательского интерфейса с помощью filtering.
  3. Может перехватывать и преобразовывать (sort, filter, map и т. Д.)

Вывод: мне следовало уделять больше внимания всем этим статьям об Angular + RxJS, потому что очень важно понимать паттерн Observable. Другой менее очевидный вывод заключается в том, что RxJS действительно хорош и предлагает много возможностей.

Заключение

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

Спасибо за прочтение!