LINUX.ORG.RU

Angular and socket.io

 , , ,


1

3

Ребята пишу небольшой application в виде чата , используя angular, express js, socket io. Вроде все не плохо, но есть одно но, отправляю я допустим сообщение, я его в чате вижу сразу, переключаюсь на второго юзера и вижу сообщение что я отправил только после того как начинаю в форме в поле input набирать текст, если делаю console.log() то в консоли все правильно отображается - сразу и динамически, как правильно ангулар заставить это дело обновлять на странице не докумекал, $scope.$apply() как я понимаю не подойдет.А вот еще ссылка на код на всякий случай. https://gist.github.com/anonymous/5584f54261574818e687/2ad35d37069ff230d76246...



Последнее исправление: Berdin (всего исправлений: 1)

socket.on('message', function(data){
  $timeout(function() {
    $scope.messages.push({
      author: 'Somebody',
      text: data
    });
  });
});

$timeout инициирует цикл $digest

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Тоесть это будет динамически обновлять $scope.messages на других клиентах и там сообщение как должно будет появится сразу, а не после начала ввода в input?

Berdin
() автор топика
Ответ на: комментарий от static_lab

Спасибо , решение помогло, к сожалению у меня на digest в angular пробел вот и не сообразил как сделать правильно.

Berdin
() автор топика
Ответ на: комментарий от Berdin

Тоесть это будет динамически обновлять $scope.messages на других клиентах и там сообщение как должно будет появится сразу, а не после начала ввода в input?

Смотри, какая тут штука: socket — это объект не из мира ангуляра, поэтому ангуляр не может автоматически отследить коллбэк на on message, а потому не знает, когда изменится $scope.message. $timeout даёт асинхронный ангуляровский коллбэк, в нём заложено, что данные определённо могут измениться и надо бы их проверить. Когда ты изменял input, срабатывал обработчик в ngModel, где вызывался $digest, который и проверял за компанию $scope.message.

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

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Ясно, очень доходчиво, теперь буду хотя бы знать почему не работало и почему теперь работает)

Berdin
() автор топика
Ответ на: комментарий от static_lab

А если вместо $timeout написать $scope.$apply, то будет работать?

socket.on('message', function(data){
  $scope.$apply {
    $scope.messages.push({
      author: 'Somebody',
      text: data
    });
  });
});
$scope.$apply вроде для того и сделан.

Black_Roland ★★★★
()
Последнее исправление: Black_Roland (всего исправлений: 1)
Ответ на: комментарий от anonymous

Заглючило меня :) Я имел в виду это:

socket.on('message', function(data){
  $scope.$apply(function() {
    $scope.messages.push({
      author: 'Somebody',
      text: data
    });
  });
});

Black_Roland ★★★★
()
Ответ на: комментарий от zz

Как вам Backbone? Meteor? Ember? Я пока плотно на первом сижу. Angular что-то руки выучить не доходят, да и не понравились мне их биндинги к view, какие-то data-атрибуты...

menangen ★★★★★
()
Ответ на: комментарий от anonymous

Давно работаешь с angular.js? Что скажешь об этом? http://www.fse.guru/2-years-with-angular

Думаю, что найти недостатки можно в любой технологии. Идеальных решений нет. Ангуляром вполне можно пользоваться. Разумеется, если писать неаккуратно, то код будет работать медленно, но это тоже можно применить к любой технологии. Вообще, мне было бы интересно посмотреть на довольно сложное приложение на любом фреймворке, которое разрабатывается в условиях хронического дедлайна.

Как мне кажется, сейчас уже накопилась критическая масса разработчиков и сторонних решений на ангуляре, которые помогают совершенствовать его в том числе и по производительности. В ангуляре 1.2 добавили $watchCollection, что ускоряет работу ngRepeat, в 1.3 добавили однократную привязку. Но так-то да, dirty-check временами огорчает.

Вообще, ангуляр позволяет выделять в директивы отдельные блоки страницы и оптимизировать их вручную. Опять же, если в этом есть необходимость. У нас была идея использовать React совместно с Angular, но мы не смогли добиться значительного прироста скорости — возможно кривые руки, возможно ангуляр и так уже оптимизировали для простых случаев.

В качестве альтернативных технологий автор предлагает использовать кучу других фреймворков, например:

1. Для простых приложений — Backbone. Проблема в том, что код получается громоздкий, а при возможном усложнении логики поддерживать его становится ещё сложнее.

2. Knockout для приложений с заделом на производительность по мне — спорное решение. Хоть у него обновление модели шустрее, но он сильно проигрывает ангуляру по работе с DOM. Если ngRepeat может только отрендерить новый элемент списка и добавить его к остальным, то Knockout вынужден переписывать весь innerHTML. Поправьте, если ошибаюсь.

3. Desktop-like приложения для меня вообще представляют вещь в себе. Полностью нативного поведения UI добиться в web-приложении невозможно, тем сильнее отличия от классического приложения будут бросаться в глаза. ExtJS может казаться выгодным из-за наличия готовой библиотеки компонентов, но на практике может возникнуть проблема с их взаимодействием при реализации сложного интерфейса. Лично мне часто приходилось либо долго и нудно лепить костыли, либо вообще переделывать интерфейс по-другому. Реализовывать собственные компоненты также может быть весьма затруднительно. Ну а времени на борьбу с фреймворком как всегда никогда не хватает.

4. Fullstack-решения вроде meteor предполагают использование его же и на сервере. Для сложных энтерпрайз-решений мне такой вариант кажется наиболее опасным: очень сильно ограничивается возможность для перехода на альтернативные технологии как на сервере, так и на клиенте, поскольку всё взаимосвязано и взаимозависимо.

Согласен, AngularJS — довольно сложная технология и без гуру освоить и применять его правильно может быть весьма проблематично. Однако нам он понравился именно тем, что позволяет дробить логику на подмодули и компоненты, которые можно при необходимости оптимизировать. К тому же позволяет относительно быстро написать рабочий прототип. Ну и любой бэкенд позволяет использовать. У нас, например, это Rails.

Можно расписывать и дальше, но так или иначе получится ведь холивар.

static_lab ★★★★★
()
Ответ на: комментарий от menangen

Я с backbone не работал, пишу чаще front-end на angular, пока его хватает со всякими штучками типа watch(), watchCollection() не знаю есть ли это в backbone,хотя подумываю освоить React.

Berdin
() автор топика
Ответ на: комментарий от static_lab

Кстати я тоже прочитал эту статью, хотел отписать свое мнение, но после твоего ответа понял что все изложено также как и я хотел это подать)

Berdin
() автор топика
Ответ на: комментарий от menangen

React и ad hoc костыли - наше все. Ember тоже не плох если нравятся рельсы.

zz ★★★★
()
Ответ на: комментарий от static_lab

Knockout вынужден переписывать весь innerHTML.

Это не так. Там проблема в том, что когда достаточно большое количество observable - очень много не batched апдейтов выходит.

zz ★★★★
()
Ответ на: комментарий от Berdin

со всякими штучками типа watch(), watchCollection() не знаю есть ли это в backbone

Там нет этого, надо ручками. И двухстороннего связывания тоже нет, надо вешать на каждый элемент обработчик onchange, и соответственно менять контент при изменении модели. После этого View заново делает рендер шаблона.

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Теперь начинаю сомневаться насчет React,хотя он использует shadow DOM, чтобы не рендерить по новой всю страницу, может и его выучить и попробовать тоже скрестить на проекте вместе с Angular.

Berdin
() автор топика
Ответ на: комментарий от Berdin

не рендерить по новой всю страницу

Так и ангуляр не рендерит каждый раз всю страницу. А ngRepeat вообще действует хитро: если добавить в выводимый массив ещё один элемент (причём неважно, где он будет добавлен), то ngRepeat только его добавит в DOM, не затрагивая остальные. Аналогично будет сделано и в случае удаления или перемещения элемента. Это даёт очень неплохой прирост производительности. Вообще следует придерживаться правила минимально создавать новые и промежуточные объекты, переиспользуя старые. Во-первых, это экономит память и время процессора на сбор мусора, а во-вторых, позволяет сократить количество обновлений частей страницы. Также следует контролировать количество вотчеров на странице, по возможности заменяя их на однократные привязки (завтра скину скрипт для посчёта, если не забуду).

может и его выучить и попробовать тоже скрестить на проекте вместе с Angular.

если есть такое желание, то можешь попробовать и проект ngReact. Он, правда, не доделан ещё.

static_lab ★★★★★
()
Ответ на: комментарий от Berdin

Правда жизни такова, что хотеть использовать реакт с чем-то вроде angular/knockout не имеет смысла. После того, как ты перестаешь использовать их для рендера - от них остается только боль и проблемы с масштабированием.

zz ★★★★
()
Ответ на: комментарий от static_lab

Скажем так, кнокаут решает вопрос биндингов моделей на вьюхи. Бакбон решает вопрос организации моделей. Ангуляр делает и то и то. Поэтому сравнивать их между собой не имеет смысла. Равно как и пытаться из бекбона вручную рулить вьюхами.

В кнокауте есть инкрементальное обновление коллекций. Но нет пакетирования апдейтов через requestAnimationFrame, к сожалению.

У себя я забил на бекбон, т.к. наиболее трудоемкая часть - это как раз биндинги на вьюхи. Ангуляр осилить так и не смог, потому что он слишком сильно вынуждает менять архитектуру приложения под его концепции. У меня на основном проекте нет особых наворотов в интерфейсе, сложные свистелки только на формах - там кнокаута пока хватает.

На втором проекте (фонтелла), есть тормоза из-за большого количества элементов в DOM. Там кнокаута маловато, но руки не доходят переделать. По большому счету, там надо над интерфейсом думать, а не над фреймворками. Хотел привенуть React, но меня смущает что там HTML вручную собирают. Как-то привык уже к jade, а как их скрещивать пока не понял.

Vit ★★★★★
()
Ответ на: комментарий от Vit

Ангуляр осилить так и не смог, потому что он слишком сильно вынуждает менять архитектуру приложения под его концепции

Да нет в ангуляре принципиально иных концепций по сравнению с нокаутом. Нокаутовский объект ViewModel — это ангуляровский $scope. Код, который заполняет scope полями и методами, помещается в контроллер. При этом логику приложения для удобства выделяют в сервисы. Директива же, это многофункциональная штука, которая позволяет привязаться к DOM, может создать scope со своим контроллером, а также может этот DOM модифицировать при помощи шаблона и функции compile, или её частного случая link.

Так что, по сути, нокаутовский код для viewmodel переносится в контроллер, который вешается на html или напрямую — директивой ng-controller, или через свою директиву. В директивы выносится и код, который напрямую модифицирует DOM. Также директивы позволяют инкапсулировать отдельные компоненты приложения. Вот и всё.

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Нокаутовский объект ViewModel — это ангуляровский $scope

Да я это понимаю. Просто ангуляр форсит все в скоп целиком заворачивать. Ну вот лично у меня такое впечатление создалось. И насколько помню, там пока не решили вопрос, как без напрягов отрендерить страницу на сервере. Например в React этот вопрос вроде бы решили. Вариант «рендерите через phantomjs» не рассматриваю.

Я какбэ не против ангуляра. Просто объясняю, почему лично для моих нужд не попёрло. Можно было бы в админку вкрячить, но решил не плодить зоопарк.

Vit ★★★★★
()
Ответ на: комментарий от Vit

И насколько помню, там пока не решили вопрос, как без напрягов отрендерить страницу на сервере. Например в React этот вопрос вроде бы решили. Вариант «рендерите через phantomjs» не рассматриваю.

вот что-то есть, но, наверное, сыровато: https://www.npmjs.org/package/angularjs-server

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Как-то ынтырпрайзненько все равно - целый отдельный сервер с роутером. Хочется ведь другое - чтобы на сервере слой рендерера был изолирован, и ангуляр можно было воткнуть в этот слой. Тогда будет тру изоморфное приложение.

Vit ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.