s1im
0
Навскидку:
1. Использовать Transclusion
2. Использовать вторичные роуты (якоря на заголовки на странице глючат, поэтом если вас перекинет не туда, сделайте поиск по странице: «Displaying multiple routes in named outlets»).
s1im
+4
Забавный опрос) Ну как можно называть маленькую библиотечку Redux фреймворком? Или React сам по себе? Или библиотеку RxJX? И т.д.
s1im
0
Я там в конце сделал сноску, что в редких случаях все же допускаю их использование. Но только в тех случаях, когда реально без этого не обойтись, как правило для сессионных данных. Ну хотя бы тот же токен пользователя надо как-то хранить, а не заставлять его авторизовываться заново, если ему приспичит нажать F5.
s1im
0
Очевидно, своей простотой и поддержкой браузерами по-умолчанию. Плюс, грамотное использование localStorage решает вопрос, когда пользователь в вашем SPA-приложении пытается открыть ссылку в новой вкладке.
s1im
0
При создании SPA, те самые элементы, которые на серверных языках я бы реализовывал через хранение данных в сессии (тот же профиль пользователя), приходится использовать storage-ы и модели, которые получают данные из них.

Т.е., поставленную вами задачу я бы решал следующим образом: создал отдельный компонент Layout, который будет показываться по-умолчанию на страницах и содержит компонент c шапкой, в котором отображаются данные авторизованного пользователя, которые берутся из сессии (т. е. из storage-а). Обновлять данные в шапке можно по ngDoCheck, а чтобы это никак не сказалось на производительности, в механизм нашей сессионной модели несложно добавить проверку на последнее изменение по Timestamp-у.

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

Но это, опять же, если я правильно понял ваш пример. Часто годятся и «оутпуты до корня». Пример: личный кабинет пользователя — корневой компонент. При создании загружает актуальные данные о пользователе и хранит их в себе. Имеет два дочерних компонента: Presentational — лэйаут (использую в нем transclusion посредством ng-content) отрисовывающий шапку, футер, и место, куда будет помещен второй дочерний компонент с формой редактирования данных пользователя. По сути, в данной схеме будет использован всего один output — от компонента с формой редактирования до корневого личного кабинета. Который после получения новых данных о пользователе тут же отобразит их в лэйауте (в шапке, без всяких ngDoCheck). И в такой схеме я вообще не вижу необходимость какого-то глобального стейта.
s1im
0
Вот у вас есть несколько несвязанных компонент, каждая из которых подтягивает копию некоторого стейта с бекенда

Исходя из моих принципов, у меня в любой момент времени нет нескольких несвязанных компонентов, общающихся с бэком. Всегда есть только один корневой (грубо говоря, текущая страница) привязанный к текущему роуту. Если роут меняется (не путать с изменением параметра роута), то этот компонент уничтожается, и создается новый компонент согласно новому роуту. И уже он грузит свой актуальный стейт с бэка.
s1im
0
Не использую общий глобальный стейт и придерживаюсь обычно следующих принципов:

  1. деление компонентов по типу Presentational и Container Components (https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0)
  2. каждый «корневой» компонент (как правило, привязанный к опредленному роуту) получает свое актуальное состояние с бэка при инициализации или изменении параметров роута
  3. корневые компоненты между собой не общаются, только через бэк
  4. корневой компонент как правило является Container Component-ом и для отрисовки передает/получает свойства своего состояния через цепочки input/output дочерним Presentational Component-ам (или, если куски большие, разбивать на несколько дочерних Container Component-ов

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

Эти принципы подробно описаны в официальной документации Angular-а и, как мне показалось, являются тем самым angular way.

В редких случаях, допускаю хранение некоторых глобальных флагов и пр. в storage-ах.
s1im
0
Часто в подобных опросах такой вариант становится лидирующим и портит вид общей статистики. Именно для этого на хабре есть кнопка воздержаться.

В данный момент: Проголосовало 152 человека. Воздержалось 150 человек. Полагаю, эти 50% пользователи как раз таки «не используют» redux.
s1im
+1
Знакомство с первым AngularJS у меня так и не состоялось, отпугнули как раз вот такие слухи о его сложности и неудобности. Но вот со второй версией случилась любовь с первого взгляда. Восхитило, насколько в нем все логично и просто устроено. Не считая, конечно, некоторой сложности в сетапе и сборке prod-версии (это был rc1, никакого Angular CLI еще не было в помине). Но, спасибо webpack-у за наше счастливое детство, сложности эти были легко преодолены.

К чему эти дифирамбы? Просто на главной странице документации redux написано, что его можно использовать с чем угодно, не только с react-ом, но и с Angular 2+. Но за все время разработки на последнем, я так и не смог придумать, для чего мне мог бы пригодиться redux.
s1im
+2
Циклом правильную задержку не сделать, рекурсией элементарно решается
const delay = 50, f = function _f(i) {
	if (i > 100) return;
	setTimeout(() => {
		let s = '';
		if (i % 3 === 0) s += 'Miss';
		if (i % 5 === 0) s += 'Kiss';
		console.log(s ? s : i);
		_f(++i);
	}, delay);
};
f(1);
s1im
0
У меня от светлых букв на темном фоне очень сильно устают глаза. Плюс, строки белых букв как бы отпечатываются на сетчатке и я их потом очень долго вижу даже когда смотрю в сторону от монитора. С белым фоном/темными буквами такой проблемы нет.
s1im
0
Спасибо за подаренный значок «отхабренный». Ранее, я хотя бы мог отвечать вам без ограничений по времени, а теперь даже этого удовольствия вы меня лишили.

А скажите, товарищ сисадмин, обслуживаете ли вы какую-либо информационную систему с данными пользователей? Если да, есть ли у вас физический доступ к бэкапам этой системы? И самое главное, что происходит с носителями, на которых эти бэкапы были записаны, после того как истек срок их службы?
s1im
0
А что вам по факту не понравилось в моем комментарии? Или вы с призывом шифровать все подряд, использовать TOR, VPN, спать с учебником по информационной безопасности под подушкой и т.д.? Каким бы безопасным не было приложение, всегда есть вероятность утечки. Ну и еще один факт, которому учат на курсах по информационной безопасности: чем безопаснее приложение, тем дороже его разработка и обслуживание, а также сложнее использование. Поэтому в коммерческой разработке никто не стремится к 100%-ой безопасности, а находят какое-то промежуточное положение, удовлетворяющее затратам бизнеса и ожиданиям пользователей.

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

Спасибо за внимание, можете сходить.
s1im
0
Не совсем, скорее, одно из его ответвлений рангом пониже.
s1im
+5
Я раньше тоже так думал, и слепо верил в «нормальность» крупных серьезных компаний. Но в качестве иллюстрации, расскажу, то довелось поработать в одной компании, которая разрабатывала портал по заказу правительства (тут без подробностей). И где-то уже через пару недель работы мне дали доступы к базе, которая содержала личные данные реальных людей, кто хоть раз авторизовался на этом портале (ФИО, СНИЛС, номер паспорта, дата рождения, адрес регистрации, информация по детям, номера ВУ и пр. пр.). На минутку, никаких вагонов бумажек, кроме стандартного NDA при приеме на работу, я не подписывал. При желании, я мог лего слить все эти данные (чего я делать не стал), например, на флешку: комп был обычным, usb-порты не были заблокированы. Так что, верить не стоит никому.
s1im
+5
Даже если отойти от модераторов и правовой стороны вопроса. Представим на минуту, что в соц. сети X есть инженер Петя, у которого есть доступ к боевой таблице БД с переписками пользователей. И вот он во время выполнения какой-то задачи или в свой обеденный перерыв делает обычный «SELECT ...» с рандомным id диалога, результатом выборки которого становится ваша переписка с вашим же знакомым. Петя пробегает глазами по переписке, ничего для себя не находит интересного, закрывает результаты выборки и продолжает заниматься своими делами. Этой вот выборкой Петя много чего нарушил, в правовом поле и не только. Но по факту, никто об этом никогда не узнает и ничего этому Пете за это не будет. Хотя тайна вашей переписки и была нарушена. Хотите приватности — общайтесь тет-а-тет. А сеть вам приватность гарантировать не может.
s1im
+40
А я не понимаю всей этой шумихи насчет скрытых фото. Именно тот момент, что все так удивляются, когда узнают, что модераторам могут быть доступны для просмотра любые материалы пользователей, пусть они хоть трижды помечены как скрытые. Фото может считаться приватным только до того момента, как оно было выложено в сеть. Как только ты вложил его на любую площадку, считай его уже посмотрели: твой провайдер, фсб-шники, держатель хостинга, админы/разрабы/модераторы площадки, хакер Вася и, наконец, все пользователи того популярного развлекательного сайта, куда Вася их выложил.
s1im
+2
Демо-пример явно недоработанный. Пока скроллим вниз — все нормально. Но если перейти в начало (нажать «Home» / перейти по якорю #) — то увидим лишь белый экран. И еще, при скролле вверх скроллбар дергается как ненормальный. Chrome 54.
s1im
+3
Вызов document.getElementById три раза вместо одного не может существенно замедлить выполнение скрипта. Дело в том, что при вызове этого метода никакой код не обходит весь DOM. Браузеры сами индексируют все элементы с id, поэтому доступ к ним получается довольно быстрым (хотя конечно не таким быстрым, как если бы вы закешировали данную выборку сами). Попробуйте сделать html файлик со следующим содержанием и загляните в консоль:
<div id="aaa"></div>
<script>console.log(aaa);</script>


Вот на что действительно следует обратить внимание, так это на глобальные выборки не по id-селекторам, по которым коду на самом деле приходится обходить весь DOM (вроде «div.some_class»).
s1im
+1
  1. short tags в php-шаблонах — не антипаттерн
  2. глобальных переменных в этой строчке нет, только объявленная константа
  3. синглотона тут тоже нет, есть вызов статического метода из класса-хелпера CUtil
  4. про шаблонизаторы спорно, но использование php-шаблонов уж точно не антипаттерн
s1im
0
Пробуйте тут (Хром, ИЕ11): jsbin.com/mevehayica/2/edit?html,js,output
s1im
0
На мобильные браузеры я бы особо пока не надеялся. По опыту, довольно сносно WebGL работает на мобильном Хроме. На мобильном Windows 8 IE пока не умеет WebGL, обещают скоро добавить, видимо, в 10 винде. На десктопе IE11 тоже хорошо справляется. А вот FF почему-то отказывается работать в WebGL контексте как на мобильном у меня, так и на десктопе, несмотря даже на все настройки в about:config — при вызове PIXI.autoDetectRenderer в FF всегда выбирается медленный «canvas» вместо «webgl». Не знаю, может руки у меня кривые.
s1im
0
Вы меня опередили. Действительно, ресайз на GPU проходит заметно быстрее при довольно хорошем качестве. Рекомендую всем желающим попробовать:
1. Подключаете PIXI.js для простоты работы и создаете сцену (var stage = new PIXI.Stage(0xffffff))
2. Высчитываете пропорции сцены и коэффициенты масштабирования по каждой стороне
3. Создаете текстуру с оригинальным изображением (var texture = new PIXI.Texture.fromImage('path/to/image'))
4. Создаете спрайт с этой текстурой (var sprite = new PIXI.Sprite(texture)), выставляете коэффициенты масштабирования (sprite.scale = {x:… ,y: ...})
5. Добавляете спрайт на сцену (stage.addChild(sprite)) и рендерите изображение (renderer = PIXI.autoDetectRenderer(newWidth, newHeight); renderer.render(stage);)

Можно и без PIXI, конечно, просто будет заметно больше кода. Но для тестов можно и так попробовать.
s1im
0
А я помнится решил проблему с помощью WebGL (для большей простоты еще и с PIXI.js). Конечно, это не для всех браузеров, но в своей админке я обычно хозяйничал сам и заходил только под Хромом. Тесты производительности не делал, но проблем и подвисаний даже с огромными изображениями не было.
s1im
+3
Реально неприятно. Было написано 0 статей, но очень много положительных комментариев, которые могли быть полезны другим читателям. От такого нововведения желания писать статьи не появилось, но и комментарии писать больше не хочется. Как плевок в лицо.
s1im
+11
Напомнило случай, когда ребятам, участвовавшим в конкурсе 10k apart, не хватало тех самых 10кб для js-кода. Тогда они (вдохновившись наработками других иностранных коллег) написали небольшой скрипт, который кодировал байты js-кода в точки для png-картинки:

image
jquery.1.8.2.min.js — 91кб до сжатия, 34кб в виде png-файла

Эту картинку можно легко нарисовать на canvas-е и считать js-код обратно, выполнив его eval-ом. Совместив эту идею с вашей котофускацией, можно сделать неплохой обфускатор js файлов, особенно если запутать код самого дешифратора.
s1im
+21
Тоже всегда путаюсь но только не в таком примере, как добавили вы, а вот в таких интерфейсах:

ON — это индикатор состояния («включено»), или подпись действия по нажатию («включить»)?
s1im
+6
Извините, ничего, так как ни разу не пользовался этим мобильным приложением. Если там этой ссылки нет, то лучше, наверное, обратиться об этом к ТМ, чтобы они добавили ее в грядущих версиях.
s1im
+2
Спасибо, не такой уж вы и useless :-) С дизайнером PS никак не могу согласиться, по-моему, он все же накосячил. Да даже эта фраза «X marks the spot» похоже на отмазку, я бы сказал «V (галочка) marks the spot».
s1im
+2
Я знаю, что значит крестик у русских. Вопрос был: «намеренно ли и для каких целей Sony ввела некоторую неразбериху в своих интерфейсах».
s1im
0
То есть, только в японской PSP, ползая по интерфейсу, кружочек будет подтверждать действие, а крестик отменять? Интересно, но все равно остается нелогичным для «неяпонцев».
s1im
+3
И что? У японцев x (Batsu), тоже, по идее, означает «нет», «неправильно».
«Batsu» in Japanese means the cross mark ( x ) you put when something is wrong.
s1im
+9
Ссылка есть в плашке под статьей, где и должна быть в интерфейсе хабра.
s1im
+10
Отдельно хотелось бы спросить про Maru (o) и Batsu (x), может быть кто знает. Почему, если Batsu означает что-то неправильное, а Maru — правильное, Sony на своих консолях использовала x — как «да», «подтвердить», а о — как «нет», «отмена» (например в интерфейсе Sony PSP)? Кстати, на этой же PSP до сих пор встречаются homebrew приложения, в которых разработчики назначают о — да, х — отмена, что вызывает очень большую путаницу при использовании таких приложений.
s1im
+1
Я тоже не понимаю, отличное издание, практически без альтернатив, особенно во времена, когда интернеты были не у всех. Но почему-то часто его упоминание вызывает волну негатива у людей. Мне вот этот комментарий даже стоил пары минусов в карму.
s1im
+13
Отлично! Напомнило почему-то статьи в старых выпусках журнала ][akep. Не сочтите за критику поста или самого журнала, я его раньше постоянно покупал и во многом благодаря ему теперь работаю в IT.
s1im
+2
Сцены разные бывают, вспомните, например:
Темный рыцарь
:
image
s1im
+1
Не получится встроить лифт всюду, где есть ступеньки. Например, переходы через улицы наших городов часто реализованы как подземные или надземные переходы. Видели хотя бы один такой с работающим лифтом? Покупать машину вместо велосипеда тоже неправильное решение, благодаря которому все более менее крупные города стоят в пробках. Смысл в такой покупке? Сидеть неподвижно и продолжать усугублять свою проблему?

По поводу запаса энергетических ресурсов который когда-нибудь пригодится — это самое глупое своей тучности, которое я когда-либо слышал. Все потому, что по пальцам пересчитать тех толстяков в 21 веке, которым это пригодилось бы.