Как стать автором
Обновить

Комментарии 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 — в переводе с инглиша «тележки». Мелочь конечно, а в глаза бросается.
НЛО прилетело и опубликовало эту надпись здесь
Все ваши комментарии ниже было интересно, но ужасно неудобно читать. В ответ на один коммент — один коммент же :)
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
angular-seed рекомендуется разработчиками angular js
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Не вижу где там на amazon слово carts, покажите мне
Правый верхний угол:
«Your Shopping Cart is empty.»
и рисунок с тележкой =)
я про cartS
НЛО прилетело и опубликовало эту надпись здесь
Для древовидной структуры я бы выбрал Mongo
НЛО прилетело и опубликовало эту надпись здесь
Не понял ваш комментарий — причем тут реляционная модель? Она тут как раз и не нужна.
НЛО прилетело и опубликовало эту надпись здесь
А как вы относитесь к тому, что человек в цикле вытягивает дерево из базы многократными запросами?

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

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

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

Да и вообще MongoDB не так просто юзать в PHP как это делается в ноде…
НЛО прилетело и опубликовало эту надпись здесь
Ко всему вышеперечисленному выше — я бы вынес загрузку данных в 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 лежит пока в загашнике и дописывается.
Конечно, на текущий сайт не смотрите, его делали не мы, и он скоро уйдёт в небытие.
А куда (когда?) смотреть?
НЛО прилетело и опубликовало эту надпись здесь
Gulp еще поможет с base64, сжатием графики, спрайтами, запуском тестов, логами и многим другим. Я свой рабочий процесс без него уже не представляю.
а каким образом gulp поможет с логами?
Честно говоря не вижу особого профита от использования gutil вне сборки на gulp. Т.к. формат логов приложения как правило отличается от формата логов gulp, в тексте логов ANSI-последовательности для раскраски логов, только мешают. Плюс невозможно кастомизировать логику записи логов. Конечно, можно воспользоваться перехватом stdout, а дальше уже отправлять сообщения в хранилище логов, однако это не очень удобный способ, т.к. в stdout могут писать и сторонние модули.
каждая картинка 100-300 кб

Как Вы так умудрились?
Вот же:
>Такая оптимизация была достигнута за счёт сжатия больших фоновых изображений без потери качества
Вероятно, и обычные картинки жали с избыточным качеством.

>Сейчас же мне удалось оптимизировать всё, и сайт весит 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 ); Но для этого надо научить ваш сервис возвращать обещания, а не прокидывать результат запроса в колбек.
Спасибо, с обещаниями ещё до конца не разобрался, хотя уже многое перечитал.
НЛО прилетело и опубликовало эту надпись здесь
Насчет первого пункта, а нельзя выгружать все товары, но просто их не рендерить, это избавит от лишних газрузок изображений? Мне кажется это афигенно, скорость поиска и просмотра товаров возрастает в разы. Так, например, контакт делает с друзьями.
$sub_category = Category::find("pid = '" . $id . "'");

Это инъекция 100%.
Я сейчас перевожу всё на mongodb, этого бреда больше не будет.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации