Ответы пользователя по тегу Angular
  • Отличия service от factory?

    AMar4enko
    @AMar4enko
    Вот хорошая статья. habrahabr.ru/post/190342
    Ответ написан
    Комментировать
  • Как скормить Angular динамические данные из Ajax.jquery?

    AMar4enko
    @AMar4enko
    Это что касается компиляции и использования шаблонов "на лету"
    codepen.io/AMar4enko/pen/azvEXw

    В остальном много вопросов по архитектуре например, что делает $scope.translate в контроллере, зачем в целом нужен контроллер language и.т.д.
    Ответ написан
    Комментировать
  • У меня не работает парочка вещей на angular, как пофиксить?

    AMar4enko
    @AMar4enko
    Насчет того, что у вас при нажатии "Заказать" добавляется в массив, но не пересчитывается сумма заказа:
    У вас mainController объявлен на body, а потом объявлен в my-directive.

    В начале mainController вы в скоупе создаете новую ссылку на массив orderList, totalPrice() вызывается на скоупе второго экземпляра mainController, в то время как добавление товара происходит в массив, объявленный в скоупе первого экземпляра mainController, а это два разных массива.

    А убрать из директивы объявление контроллера вы не можете, потому что для директивы запрашиваете изолированный скоуп, в который само собой функция totalPrice() из скоупа, объявленного на body, не попадает.

    Вам надо основательно разобраться сначала, как работаю скоупы в AngularJS, после чего узнать про controller as.

    P.S. По архитектуре приложения ничего говорить не буду, не просили.

    Вы столкнулись с проблемой из-за того, что захардкодили в контроллерах бизнес-логику. Это очевидный архитектурный недостаток. После его устранения у вас все начнет работать как нужно. Вам нужно вынести работу с корзиной в отдельный сервис:
    module.service('Cart', function($rootScope, localStorageService){
        var 
            currencies = {rub: 10800, usd: 1}, 
            cartTotal = 0, 
            cartItems = localStorageService.get('zakaz') || [];
    
        function updateCartTotal(){
            var _total = 0;
            angular.forEach(cartItems, function(item){
                _total += item.price;
            });
            cartTotal  = _total;   
        }
    
        this.getTotal = function(currency){
            var currency = currency || 'usd';
            return cartTotal * (currencies[currency] || 1);  
        }
        this.addItem = function(item){
            cartItems.push(item);
            updateCartTotal();
            $rootScope.$broadcast('cart:updated', {cartSize: cartItems.length});       
        }
        this.removeItem = function(item){
            var idx = cartItems.indexOf(item);
            if(idx > -1){
                cartItems.splice(idx,1);
                updateCartTotal();
                $rootScope.$broadcast('cart:updated', {cartSize: cartItems.length});       
            }
        }
        this.isItemAddedAlready = function(item){
            return cartItems.indexOf(item) > -1; 
        };
        this.clear = function(){
            cartItems.length = 0;
            cartTotal = 0;
            $rootScope.$broadcast('cart:updated', {cartSize: cartItems.length});   
        }
        this.getItems = function(){
            return cartItems;
        }
    });

    Замечание: сейчас для поиска элемента в массиве ипользуется indexOf.
    Он будет работать только когда корзина будет инициализироваться пустым массивом, потому что в этом случае при добавлении и удалении элементов будут использоваться одни и те же ссылки и равенство ссылок будет прокатывать. Для нормальной работы нужно либо писать костыль для поиска по ID, либо использовать underscore или lodash.

    Теперь вы в контроллеры подключаете этот сервис через DI и везде, где нужно, используете его методы.
    Для того, чтобы обновлять сумму и размер корзины делаете:
    $scope.$on('cart:updated', function(event, info){
        $scope.cartTotal = Cart.getTotal(currency);
        $scope.cartSize = info.cartSize;
    });

    Мы бы могли сохранить ссылку на функцию сервиса у себя в контроллере и в шаблоне вызывать ее, типа {{getTotal(currency)}}, но так делать не стоит, потому что это лишний нагруженный watcher. Сейчас вы его, конечно, не почувствуете, но помнить о таких моментах надо всегда. Поэтому мы подписались на событие корзины и когда корзина изменяется, вытаскиваем нужную информацию.
    Перепишите код с использованием сервиса, и увидите как он изменится в лучшую сторону. Ну а про удобство автоматизированного тестирования пока, думаю, смысла нет.
    Ответ написан
  • Как сделать код рабочим для promise Angular?

    AMar4enko
    @AMar4enko
    Вы бы написали, как insurances в скопе появляются.
    Может быть достаточно $scope.insurances = [];, может быть стоит получение данных вынести в resolve-секцию. Вариантов уйма, у всех свои плюсы и минусы.
    Ответ написан
  • Как скрыть/показать блок в зависимости от выбранного элемента списка?

    AMar4enko
    @AMar4enko
    Не используйте ng-repeat для options внутри select, для этого есть ng-options.
    $scope.yesNoOptions = [
        {value: 'Y', title: 'Да'},
        {value: 'N', title: 'Нет'}
    ];
    $scope.applications = [
        {id: 1, title:  'Application title', ...},
        ...
    ];

    <select id="autoAppl" class="form-control auto_applications" ng-model="autoApplication" ng-options="opt.value as opt.title for opt in yesNoOptions">
    </select>
    <div class="new_service applications" ng-show="autoApplication == 'Y'">
        <label for="listApplications">Список заявок</label>
        <select id="listApplications" class="form-control list_applications" ng-options="app.id as app.title for app in applications">
        </select>
    </div>
    Ответ написан
  • Angular. Как подгрузить HTML тэмплейт по определенному событию?

    AMar4enko
    @AMar4enko
    <div ng-if="showTemplate">
        <div ng-include="path/to/your/template.html"></div>    
    </div>
    <button ng-click="showTemplate = true;">Show template<button>
    Ответ написан
    Комментировать
  • UI для angular.js?

    AMar4enko
    @AMar4enko
    Не совсем понятна суть вопроса. Какая задача-то?
    Ответ написан
  • Что лучше использовать для фейковых запросов на сервер?

    AMar4enko
    @AMar4enko
    Нормальное решение с моком, вполне. Не знаю, чего это у вас сеньор такой бука.
    Ответ написан
  • Почему в yii2 отменяется запрос и запускается handleFatalError при CORS?

    AMar4enko
    @AMar4enko
    Ошибка
    No 'Access-Control-Allow-Origin' header is present on the requested resource

    на имеет к Yii никакого отношения, судя по вашему сетапу.

    Я не силен в апаче, но по-моему у вас mod_headers добавляет эти ваши заголовки только в случае 200 статуса ответа, во всяком случае в документации написано так:
    The default value of onsuccess may need to be changed to always under the circumstances similar to those listed below.

    Попробуйте написать:
    Header always set Access-Control-Allow-Origin "*"
    Ответ написан
  • Как лучше сохранить состояние сервиса между модулями angular?

    AMar4enko
    @AMar4enko
    При первой попытке ресолва сервиса в каком-либо месте вашего приложения он инстанцируется и остается жить до тех пор, пока приложение не завершится.
    angular.module('my-module', [])
      .service('usefulService', function(){
          var usefulVar = 0;
          this.doSomethingUseful = function(){ userfulVar += 1; return usefulVar; };
          this.getUsefulVar = function(){ return usefulVar; } 
      });


    Когда вы usefulService заинжектите в контроллере, функция-конструктор сервиса выполнится один раз и впоследствии во всех местах приложения будет использоваться этот инстанс сервиса.
    Следовательно такой сервис будет хранить свое состояние глобально для всего приложения.
    Если это не является ответом на ваш вопрос, то значит вы сформулировали его неверно.
    Ответ написан
  • Можно ли уже пробовать Angular 2.0? Или пора ли использовать ES6?

    AMar4enko
    @AMar4enko
    Конечно, берите двойку (где-нибудь)! Заодно альфа-тестером поработаете.
    Ответ написан
  • Ionic Framework, ui-router - как победить навигацию в табах?

    AMar4enko
    @AMar4enko Автор вопроса
    Вобщем если кому интересно - могу написать, к какому решению я пришел.
    UPD. Решение такое:
    1. Использовать $ionicViewService.clearHistory для очистки истории навигаций внутри ion-nav-view.
    Когда я в своем примере перехожу на шаг 1, то в соотв. контроллере в самом начале я чищу историю, при выходе с шага 2 в другую вкладку я тоже чищу историю. Сервис определяет, какой именно стек чистить, по видимым вьюхам.
    2. Не использовать href в ion-tab. Он их обрабатывает как-то по-своему, для того, чтобы активировать вкладки.
    Т.е. если написать href="#/tab/common/state1" и в табе было ранее когда-то активировано состояние state2, то активируется этот таб и будет отображено state2, хотя просили state1.
    Если сделать $state.go('tab.common.state1'), то отобразится state1, но только тогда, когда таб уже активен! Это вытекает из третьего пункта.
    3. Deep Linking с табами не работает. Т.е. если на холодную запустить приложение с url #/tab/common/step1, который отображается во второй вкладке, то ничего не произойдет, потому что при запуске будет активна первая вкладка. Тут вот чувак с тем же самым столкнулся
    https://github.com/driftyco/ionic/issues/2442. Я решил этот вопрос в лоб, повесив на сами табы контроллер, в котором исходя из текущего состояния вручную активирую нужную вкладку через $ionicTabsDelegate.

    P.S. Поведение, как у меня в примере, которое меня не устроило, является корректным, вот заводской пример codepen.io/ionic/pen/odqCz
    Ответ написан
  • Как настроить роутер?

    AMar4enko
    @AMar4enko
    А что сделать-то хотите?
    Вы написали "Если ни один из вышеперечисленных роутов не подошел, то отправить на страницу /catalog/:categoryId".
    Смысла в этом я никакого не вижу.
    Напишите redirectTo: '/catalog/1', отработает первый роут с categoryId 1, а если вам нужно на этапе конфигурирования приложения вместо этого 1 подставить что-то, что передается с сервера, то можете на этапе вывода шаблона записать в него JS типа
    angular.module('server-values',[]).constant('INITIAL_CATEGORY_ID', Сюда_ID);

    Подключить этот модуль в ваше приложение и тогда сможете сделать
    servicesCatalog.config(function ($routeProvider, $compileProvider, INITIAL_CATEGORY_ID) {
    //....
                otherwise({
                    redirectTo: '/catalog/'+INITIAL_CATEGORY_ID
                });
    });

    но это отдает ортопедией
    Ответ написан
  • Как загрузить данные с возможно разными типами в контроллер?

    AMar4enko
    @AMar4enko
    Так вы сами себе противоречите.
    Но, мне сейчас крайне важно иногда не выходить из потока
    и при этом допускаете, что может вернуться promise.
    Вероятно, у вас где-то недопонимание. Опишите ситуацию более детально.
    Ответ написан
    Комментировать
  • Как лучше организовать обновление данных в html виджетах?

    AMar4enko
    @AMar4enko
    Я бы сделал вариант Б.
    Недостаток варианта А - плохо согласуется с REST и надо допиливать сервер.
    Недостаток варианта В - подходит, только если дочерних элементов немного, и надо допиливать сервер.
    Ответ написан
    Комментировать
  • Как найти ключ массива по значению в многомерном массиве ?

    AMar4enko
    @AMar4enko
    Нативной функции нет.
    Если вы не против underscore или lodash, то
    _.find($rootScope.categories, {id: $routeParams.categoryId})
    Ответ написан
    Комментировать
  • Angularjs. Почему изменения на странице происходят только после $apply?

    AMar4enko
    @AMar4enko
    Покажите вызов события из директивы. Предполагаю, что проблема там.
    Ответ написан
  • Angularjs, роутинг. Как убрать хеш теги из ссылок, сохранив возможность обновления страницы?

    AMar4enko
    @AMar4enko
    Зависит от того, где запускаете. Если, например, за nginx, то в нем в конфигурации прописывают специальное правило, которое исходя из User-Agent по всем роутам показывает index.html, а angularjs по location сам все разруливает.
    Ну и во всех остальных случаях подход аналогичный.
    Просто иногда бывает нужно "живому" пользователю отдать angularjs приложение, а поисковому роботу заранее подготовленную статику. Если роботы вас пока не интересуют, то просто вне зависимости от url отдавайте index.html
    Ответ написан
    Комментировать
  • Angularjs фильтрация в бесконечном скролле без костылей?

    AMar4enko
    @AMar4enko
    А в чем конкретно у вас проблема? Там же ng-repeat. Стандартная фильтрация не канает?
    Ответ написан
  • Angularjs как правильнее сделать загрузочный экран?

    AMar4enko
    @AMar4enko
    Используйте модуль deferredBootstrap, чтобы загрузить все необходимые данные перед инициализацией приложения, не надо будет городить эти самые очереди.
    Ответ написан