Pull to refresh

Comments 55

По поводу клиента:
1. Вы пишете «полезный мануал, который пригодиться мне и другим, начинающим писать на AngularJS»
angular.codeschool.com/ и github.com/angular/angular-seed в качестве наглядного примера по структурированию.
2. Почитайте github.com/johnpapa/angularjs-styleguide и откроете для себя много интересного.
3. Ваш код не будет минимизироваться в рабочий, т.к. он должен быть размечен либо с использованием ngAnnotate, либо через $inject, либо как-нибудь ещё.
4. Откройте для себя RESTful API уже.
5. >показать пользователю preloader при каждом запросе, да и это в любом случае хороший тон
А вот тут можно и поспорить, смотря что за запрос. Если увесистый то да, но если же это обычный запрос, то это будет выглядеть как дерганье экраном.
6. Честно говоря не понял что за проблемы у вас произошли с localStorage и зачем вы в принципе искали «библиотеку» для работы с localStorage, но то, что angular ругнулся на дубликаты, говорит о неверной структуре сохраняемой информации. Я бы сделал array of objects вида {id: X, title: «XXX», count: X} (title чтобы не подгружать ничего лишний раз, но при вашем условии, когда все товары сразу на странице, можно обойтись и id товаров. Тут конечно можно подискутировать (аля старая информация в кеше и т.д.)
7. По поводу $$hashKey — stackoverflow.com/questions/18826320/what-is-the-hashkey-added-to-my-json-stringify-result
8. $locationProvider.hashPrefix('!'); вместе с $locationProvider.html5Mode(true); наводит на мысли что вы пытаетесь использовать history-api вместе с #!.. Надо ли вам объяснять в чем разница между этими двумя подходами?

По поводу сервера не джедай, но опять же, наблюдаю: SQL-запросы в цикле, необоснованный выбор MySQL, не красивый код и так далее.

//p.s.: carts — в переводе с инглиша «тележки». Мелочь конечно, а в глаза бросается.
UFO just landed and posted this here
Все ваши комментарии ниже было интересно, но ужасно неудобно читать. В ответ на один коммент — один коммент же :)
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
angular-seed рекомендуется разработчиками angular js
UFO just landed and posted this here
UFO just landed and posted this here
Не вижу где там на amazon слово carts, покажите мне
Правый верхний угол:
«Your Shopping Cart is empty.»
и рисунок с тележкой =)
UFO just landed and posted this here
Для древовидной структуры я бы выбрал Mongo
UFO just landed and posted this here
Не понял ваш комментарий — причем тут реляционная модель? Она тут как раз и не нужна.
UFO just landed and posted this here
А как вы относитесь к тому, что человек в цикле вытягивает дерево из базы многократными запросами?

>Если Вы считаете нормальным в заказе хранить копии товаров
В заказе как таковом я бы хранил ссылки на товары. В заказе как в транзакции имеет место копирование, разумеется. Модель из вашего примера «с описанием» используется к примеру на AliExpress — купленный товар копируется и при этом остается ссылка на оригинальный товар. Тут зависит уже от самого магазина конечно. Мы же говорим про доставку продуктов. Зачем нам нужно копировать на них описание? Как их хранить — это дело бизнес-процесса. Если допустим обработка идет в виде «1 пицца в соусе сальса, 2 картофеля фри» то удобнее заказ будет хранить в виде копирования списка заголовков с ценами на момент продажи, а также данных клиента для доставки/дозвона, никакой избыточной информации при этом не потребуется. Анализ продаваемости можно хранить при этом либо в отдельных документах готовых отчетов, либо прямо в товарах — вполне будет документ-вей.

>Я делал магазины и могу с ответственностью сказать, что реляций там внутри дохренища
Ваше личное дело. Я тоже делал магазины и в основном обходился документами чуть менее чем полностью
UFO just landed and posted this here
Конечно высказывание
Анализ продаваемости можно хранить при этом… прямо в товарах
для какого-то абстрактного общего случая не очень хорошее. Для этого лучше юзать map-reduce, скорее всего, но зависит от случая.

С таким подходом аналитики будут класть БД каждым запросом.
Сиииильно сомневаюсь.
Начнём с того, что в денормализации нет ничего плохого.
Ссылка на объект в документарной БД — это тоже нормально. В Mongoose есть удобный populate на этот случай.
Выбирать РСУБД стоит только тогда когда это действительно необходимо, например, если вам нужны транзакции и/или контроль целостности данных. В остальных случаях — это дело вкуса.
MySQL сама по себе не плохая но и не самая быстрая/удобная/функциональная СУБД.
MongoDB шустрая, простая, легко поддаётся горизонтальному масштабированию средствами из коробки. Причём контроль целостности данных можно без труда реализовать в моделях.

Да и вообще MongoDB не так просто юзать в PHP как это делается в ноде…
UFO just landed and posted this here
Ко всему вышеперечисленному выше — я бы вынес загрузку данных в resolve роутов.
И тоже не особо понял чем не угодил в данном случае MySQL и почему ngAnnotate не справится с аннотированием. Со стандартными регистрациями angular'овских компонентов (и даже некоторых сторонних плагинов, например resolv'ы ui-router'а) он отлично справляется без дополнительной помощи. В свои компоненты, при использовании например $injector'a, да, иногда надо добавлять /*@ngInject*/
>if ($this->request->isAjax() == true)
WIN, просто WIN

Еще можно так:
if ( ( ($this->request->isAjax() == true) && ( (!$this->request->isAjax()) == false) ) == true)
Чтобы совсем уж наверняка, так сказать :)
Ну что набросились то, человек же старался… :)
Если уж и сравнивать с true, то только оператором === (https://php.net/manual/ru/language.operators.comparison.php)
Иначе совсем уж бредово)
На самом деле есть один аргумент в пользу такого избыточного синтаксиса — он повышает читабельность кода. Т.к. мозгу проще на ходу сравнить два значения, чем заметить, что объявлено только одно значение и следует его сравнить с true. Возможно это звучит смешно, когда мы говорим об одной строке. Но, когда читаешь много кода «по горизонтали» такие мелочи действительно очень упрощают жизнь.

Как вариант еще можно if(true == $this->request->isAjax())

ну тут уже название функции все ясно показывает: if(...isAjax()) = если запрос через аякс, и никаких сравнений не нужно, почти обычный английский язык
Уже лучше, но не останавливайся.

$this->response->setContent(json_encode($products));

У нас можно делать так (JSON_UNESCAPED_UNICODE что бы русские буквы в выдаче не корявило):
$this->response->setJsonContent($products, JSON_UNESCAPED_UNICODE);
Я не могу понять кое-чего только…
Вы несколько раз говорите «стиль написания не важен, не люблю терять на него время». У Вас же PhpStorm стоит? Настройте себе там стиль (там уже есть пачка пресетов популярных Codind Style), а дальше IDE сама всё сделает. Вы потратите ровно секунду на то, чтоб ткнуть Ctrl + Alt + L, а потом Enter и привести весь код в порядок.
если пользователь перейдя по ссылке /#!/menu/7 нажмёт кнопку «Обновить страницу», он увидит вместо нормальной страницы просто json данные

Но как вы этого добились? В SPA сервер при таком запросе должен как всегда вернуть индекс, а дальше уже роутинг в JS решает, что делать. Не понимаю, как у вас вышло показать JSON вместо страницы. Да ещё и решить эту проблему костылями проверки типа запроса с серверной стороны.
я так понял у человека index отдается phalcon'ом, и роутинг phalcon'а совпадает с роутингом фронта, поэтому так и выходит… Но вообще да, правильно на любой запрос вернуть index…
Но у него же хеш после корня идёт.
За предыдущую статью поставил минус (без сожалений).
За эту плюс (недостатки есть, но прогресс очень приличный) и в карму плюс (за стремление к совершенству).
по 1,5 секунды отдаёт страницу, сколько у вас сейчас нагрузка-то?

неосилил почему сайт называется одностраничным, он же перезагружается целиком при клике на пункты меню как минимум?
Шутите? Секунд 40 первый раз грузилась главная.
И таки загрузилась, но сайт сделан на OpenCart, похоже версия на angular лежит пока в загашнике и дописывается.
Конечно, на текущий сайт не смотрите, его делали не мы, и он скоро уйдёт в небытие.
А куда (когда?) смотреть?
UFO just landed and posted this here
Gulp еще поможет с base64, сжатием графики, спрайтами, запуском тестов, логами и многим другим. Я свой рабочий процесс без него уже не представляю.
а каким образом gulp поможет с логами?
Честно говоря не вижу особого профита от использования gutil вне сборки на gulp. Т.к. формат логов приложения как правило отличается от формата логов gulp, в тексте логов ANSI-последовательности для раскраски логов, только мешают. Плюс невозможно кастомизировать логику записи логов. Конечно, можно воспользоваться перехватом stdout, а дальше уже отправлять сообщения в хранилище логов, однако это не очень удобный способ, т.к. в stdout могут писать и сторонние модули.
Вот же:
>Такая оптимизация была достигнута за счёт сжатия больших фоновых изображений без потери качества
Вероятно, и обычные картинки жали с избыточным качеством.

>Сейчас же мне удалось оптимизировать всё, и сайт весит 3,9 мб во время первой загрузки, и не больше 1 мб в последующие, так как браузер кеширует всё что нужно.
А наши пользователи справедливо жалуются на 2,2 мб / 0,4 мб (включая случайные рекламные баннеры), при том что интернет весьма шустрый, так что сайт автору ещё оптимизировать и оптимизировать.
Вот тут:

ProductsService.getData($routeParams.id).success(function(data){
$scope.items = data;
});

Заметил, что вы не словили error колбек. Это важное.
Из не особо важного:
1. Я бы ProductsService здесь назвал с маленькой буквы, т.к. вы уже здесь работаете с инстансом, хотя в JS с объектами и классами все не так однозначно.
2. getData я бы предложил назвать getProducts; data – products; productsService – productsRepository; все три мысли только с одной целью: заставить ваш код говорить более точно всякому, кто его читает. Раз вы пишете мануал – это будет трижды полезно.

Вообще ангуляр позволяет и такие чудеса делать: $scope.items = ProductsService.getData( $routeParams.id ); Но для этого надо научить ваш сервис возвращать обещания, а не прокидывать результат запроса в колбек.
Спасибо, с обещаниями ещё до конца не разобрался, хотя уже многое перечитал.
Читал и исходную статью, и эту ревью — автор, а зачем использовать такие инструменты, что сайт грузит 4Мб единомоментно после рефакторинга? И это при медленном интернете? И перезагрузка вызывает перекачку 25%? По себе — у меня медленный интернет 3Mbps, и извините, но ждать 15 секунд старта сайта для заказа пиццы я бы не стал. Максимум — позвонил оператору, а скорее убил закладку и ушел к конкуренту. История живо напоминает байку про композер, который жрет оперативку в лучших традициях java-интерпрайза.
Насчет первого пункта, а нельзя выгружать все товары, но просто их не рендерить, это избавит от лишних газрузок изображений? Мне кажется это афигенно, скорость поиска и просмотра товаров возрастает в разы. Так, например, контакт делает с друзьями.
$sub_category = Category::find("pid = '" . $id . "'");

Это инъекция 100%.
Я сейчас перевожу всё на mongodb, этого бреда больше не будет.
Sign up to leave a comment.

Articles