• Как отлавливать вводимые данные из каждых форм?

    @SuperOleg39ru
    Front-end разработчик
    При рендере массива через ng-repeat, введенные данные и так будут применяться к свойству соответствующего объекта.

    Если вам нужно отправлять эти данные в другие объекты, а не только в этот массив, то добавьте к каждому инпуту on-change, передавая туда текущий $index что бы идентефицировать форму.

    Еще лучше, для объектов массива educations добавить свойство id с действительно уникальным идентификатором, и пусть этот id создается на лету, при добавлении нового объекта.
    Ответ написан
    Комментировать
  • Как настроить webpack-dev-server с использованием historyApiFallback?

    @SuperOleg39ru
    Front-end разработчик
    Webpack начинает искать файлы по неправильному пути, добавляет в начале /movie/ в вашем скрине.
    Не могу точно сказать в чем проблема, давайте попробуем так:

    Для начала замените output.filename: './dist/main.js' на:
    output: {
            filename: '[name].bundle.js',
            path: path.resolve(__dirname, 'dist')
        }


    А publicPath: '/dist/' на:
    contentBase: path.resolve(__dirname, 'dist')

    И css выделяйте так - new ExtractTextPlugin('[name].css'), output.path уже указывает, что надо выгружать все в dist
    Ответ написан
  • Как обновить дочерний компонент из родительского?

    @SuperOleg39ru
    Front-end разработчик
    Во первых, вы объявили переменную btn, но не возвращаете ее в render.

    Во вторых, зачем объявлять в Child this.state свойство someVar, если оно доступно вам из this.props?

    Нет необходимости биндить this Child на коллбэк App, потому что тогда props.setVar метод будет вызывать setState у Child - this.props.setVar.bind(this, this.state.someVar)}

    Вкратце, React сам обновляет компонент, если изменились его props (что происходит через коллбэк родителя).

    export default class App extends Component {
        constructor(props) {
            super(props);
    
            this.state = {
                someVar: 0
            }
    
            this.setVar = this.setVar.bind(this);
        }
    
        setVar(some) {
            this.setState({someVar: some});
        }
    
       render() {
            return (<Child someVar={this.state.someVar} setVar={this.setVar} />);
       }
    }
    
    export default class Child extends Component {
        constructor(props) {
            super(props);
    
            this.handleClick = this.handleClick.bind(this);
            this.getNext = this.getNext.bind(this);
        }
    
        getNext() {
            return this.props.someVar + 1;
        }
    
        handleClick() {
            this.props.setVar( this.getNext() )
        }
    
       render() {
           let btn = (<button type="button" onClick={this.handleClick}>Go</button>
           return (<div><btn /> {this.props.someVar}</div>);
       }
    }
    Ответ написан
  • Как ставить темы для Ангуляра?

    @SuperOleg39ru
    Front-end разработчик
    Если тема = верстка + отдельные angular компоненты, скорее всего вам надо:

    1) Сделать корневой роут, который будет содержать только файл шаблон с версткой общей разметки админки, и там указать место, куда будут выводиться роуты-потомки (контент конкретных страниц)

    2) Angular компоненты темы (скорее всего они будут оформлены в один модуль) подключить в зависимость вашего основного модуля приложения

    // пример роутов, использую ui-router
    $stateProvider.state('admin', {
      template: '...', // содержит <div ui-view></div> для вывода потомков, например роута home
    })
    
    $stateProvider.state('home', {
      parent: 'admin',
      template: '...',
      controller: '...'
    })


    // Пример как выглядит angular тема INSPINIA
    export default angular.module('inspinia', [ ])
        .directive('...', ...)
        ...
        .name;
    Ответ написан
    Комментировать
  • Какой выбрать поддерживаемый boilerplate для ES6/typescript?

    @SuperOleg39ru
    Front-end разработчик
    На самом деле, это как раз тот случай, когда надо изобретать велосипед)
    Все что вы хотите - это просто конфиг вебпака и набор команд для запуска, dev и production.

    Соответственно вам надо установить webpack и webpack-dev-server, показать откуда брать файлы, как обрабатывать (за это отвечают loaders), и куда их собирать - не поленитесь изучить вебпак, можете посмотреть этот скринкаст

    Вот простой пример, я использую этот шаблон для изучения typescript.
    Правда webpack 1 уже deprecated, но разница в конфиге не критичная, так что скринкаст все-равно актуален.

    Нужен ES6 одновременно с typescript - добавляете babel-loader
    Нужен css препроцессор - добавляете loader к этому препроцессору
    Нужен линтинг - устанавливайте eslint и конфиги Airbnb
    Ответ написан
    6 комментариев
  • Как выцепить день, месяц и год из input date для замены даты в зависимости от поставленной?

    @SuperOleg39ru
    Front-end разработчик
    Допустим value - это текущее значение поля ввода.

    const year = new Date(value).getFullYear();

    И так далее)
    Ответ написан
    3 комментария
  • Gulp для верстальщика?

    @SuperOleg39ru
    Front-end разработчик
    Пример шаблона с использованием Gulp 4: https://github.com/SuperOleg39/gulpApp-example

    Стандартов нет, общие рекомендации такие - разбивать таски по отдельным файлам, определять вид сборки через process.env.NODE_ENV (и минифицировать только production сборку), хранить все пути в одном месте.

    ES6 использовать не обязательно, замедляет начало сборки.
    Ответ написан
    Комментировать
  • С чем может быть связана ошибка?

    @SuperOleg39ru
    Front-end разработчик
    Возникла проблема с разрешением зависимостей.

    Попробуйте сервис, на которые ругается angular, инжектить принудительно перед его использованием, а не как аргумент функции.

    Пример:
    const requestManager = $injector.get('requestManager');
    Ответ написан
  • Как влиться в тренд нынешней веб-разработки?

    @SuperOleg39ru
    Front-end разработчик
    Добрый день!

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

    flexbox, grid layout
    - это css из современных стандартов. Что бы знать, когда применять - вы должны знать версии старых браузеров, которые необходимо поддерживать на вашем проекте, и соответствующую поддержку этих стилей. Например, формировать элементы на flexbox на порядок удобнее, чем на float, но в IE9 вы уже использовать flexbox не можете.
    Немного о новинках в css тут.
    Поддержка браузерами тут.

    gulp, webpack и пр.
    - это инструменты, которые созданы для облегчения рутинных задач.
    Для верстки очень удобно использовать gulp - вы описываете задачи, такие как создание локального сервера, мгновенная перезагрузка страницы при изменениях, минификация ваших файлов, и прочее.
    Посмотрите отличный скринкаст от Ильи Кантора!

    препроцессоры
    - представьте, что вам чего-либо не хватает в html и css.
    Например, вы хотите разбивать большие html файлы на множество мелких, или вам нужно вставить в html динамическое содержание - для этого созданы html шаблонизаторы. Вы используете в работе синтаксис конкретного шаблонизатора, затем тот же gulp автоматически собирает эти файлы в обычный html, который понимает браузер.
    Аналогичная ситуация с css, препроцессоры позволяют разбивать файлы на мелкие, и собирать в один, доступны переменные и функции, и многое другое.
    Популярный шаблонизатор Pug
    Один из css-препроцессоров Stylus

    пакетные менеджеры
    - это удобный способ скачать конкретные библиотеки, и переносить их из проекта в проект. Статья про npm тут

    Ну и конечно статьи и подкасты:
    https://habrahabr.ru/
    jsraccoon.ru

    https://soundcloud.com/web-standards
    https://radiojs.ru/

    Конкретные статьи и ресурсы для новичка:

    frontender.info/a-baseline-for-front-end-developers
    frontender.info/a-guide-to-flexbox
    css-live.ru/articles-css/pravilnye-kontrolnye-toch...
    https://medium.com/russian/%D0%BE%D1%82-%D0%BD%D1%...
    https://medium.com/russian/%D0%BE%D1%82-%D0%BD%D1%...
    https://habrahabr.ru/company/zfort/blog/321214/
    https://frontendmasters.gitbooks.io/front-end-hand...

    Дерзайте!
    Ответ написан
    6 комментариев
  • Как побороть долгую компиляцию pug файлов в Gulp?

    @SuperOleg39ru
    Front-end разработчик
    Попробуйте использовать плагин gulp-changed

    Так же на глаза попался такой плагин - gulp-pug-inheritance

    Так же, gulp (в 4-й версии точно), имеет опции для метода src
    Как использовать, можете увидеть в скринкасте Кантора урок 5
    Ответ написан
  • Делаю директиву Angular вида autocomplete. Как правильно передавать параметры?

    @SuperOleg39ru
    Front-end разработчик
    Логика передачи параметров следующая:
    Что в html шаблоне разделяется дефисами (on-find, on-click) - то в свойстве scope пишется через camelCase (onFind, onChange);

    Так что можете упростить до:
    {
        users: '=',
        onFind: '&'
    }
    Ответ написан
    2 комментария
  • Правильный ли способ обновления данных в reducer?

    @SuperOleg39ru
    Front-end разработчик
    Сделайте декомпозицию редьюсера на несколько поменьше.
    ссылка
    Ответ написан
  • Что не так с webpack?

    @SuperOleg39ru
    Front-end разработчик
    Удалите babel-loader из конфига, точнее не добавляйте эту настройку в режиме разработки:
    {
            test: /\.(js|jsx)$/,
            exclude: /node_modules/,
            loader: 'babel',
            query: {
              cacheDirectory: true,
              plugins: ['transform-runtime', 'transform-decorators-legacy'],
              presets: ['es2015', 'react', 'stage-0']
            }
          }


    И не ленитесь изучать, как работает webpack, все окажется очень легко и понятно.
    Ответ написан
  • Как подключить сервис авторизации в angular 1.5 component way?

    @SuperOleg39ru
    Front-end разработчик
    Добрый день!

    Проверка прав может быть на:
    1) Доступ к странице - относится к роутингу
    2) Выполнение http запроса - для этого есть http interceptor
    3) Просмотр конкретных DOM-элементов - достаточно простой директивы
    А так же непосредственная проверка прав в любом месте кода, если этого не достаточно.

    Есть отличная библиотека, которая предоставляет вам готовое решение для проверки прав.

    Что касается rootScope - вам надо один раз, перед загрузкой любой из страниц (на которую требуются особые права), получить с сервера профиль пользователя. Можете создать для него соответствующий сервис, или получать и хранить его в сервисе, который отвечает за сессию, и всегда будете иметь доступ к профилю.
    Ответ написан
    Комментировать
  • Как запустить перерисовку на Angular, если изменился родительский объект?

    @SuperOleg39ru
    Front-end разработчик
    Добрый день.

    Вам нужно сделать сервис storageService полноценной моделью.

    То есть, описываете свойства модели, и методы, что бы получать и изменять эти свойства.
    Простой пример, используя систему событий Angular:
    export default class StorageService {
      constructor($rootScope) {
        'ngInject';
        this.$rootScope = $rootScope;
        this._model = {};
      }
    
      getModel() {
        return this._model;
      }
    
      setModel(newModel) {
        this._model = newModel;
        // вызываем событие Сервис изменился, при каждом изменении модели
        this.$rootScope.$broadcast('storageServiceChange');
      }
    
      loadFromFile(fileName) {
        fs.readFile(fileName, 'utf-8', (err, data) => {
            let newModel = JSON.parse(data);
            this.setModel(newModel);
        });
      }
    }


    И в контроллере подписываемся на модель:
    class AppController {
      constructor($rootScope, $scope, storageService) {
            'ngInject';
            this.storage = storageService;
            this.$rootScope = $rootScope;
            this.$scope = $scope;
            this.model = {};    
      }
      
      $onInit() {
        this.storage.loadFromFile('storage.txt');
        // подписываемся на событие Сервис изменился, и обновляем модель
        this.$rootScope.$on('storageServiceChange', () => {
            this.model = this.storage.getModel();
        })
      }
    }
    Ответ написан
  • Почему из трех вариантов инициализации controller работает только третий?

    @SuperOleg39ru
    Front-end разработчик
    На самом деле не работает ни один из вариантов.

    Просто ваша директива получает в качестве контроллера функцию mailListCtrl, которую вы и объявили в 3 варианте.

    Оберните название контроллера в кавычки:

    mailApp.directive('mailList', function(){
        return {
            restrict: 'E',
            templateUrl: 'mailListDirective.html',
            controller: 'mailListCtrl',
            // replace: true,
            controllerAs: 'mailListCtrl'
        };
    });


    Еще лучше, если вы начнете использовать компоненты, появившиеся в Angular 1.5+

    А вот стартовый шаблон, использующий вебпак для сборки и синтаксис ES6, так выглядит современное приложение на Angular 1.
    Ответ написан
    1 комментарий
  • Почему webpack пытается загрузить изображения?

    @SuperOleg39ru
    Front-end разработчик
    Добрый день!

    Документация на html-loader

    By default every local <img src="image.png"> is required (require('./image.png')). You may need to specify loaders for images in your configuration (recommended file-loader or url-loader).


    То есть, атрибут src автоматически считается вызовом изображения.

    Что бы изображение нашлось, во-первых в ваш source добавьте папку с изображениями, во-вторых начинайте пути с '/' (пример src="/img/omron2.png"), и изображения webpack будет искать относительно настройки:
    resolve: {
        root: path.resolve(__dirname, 'source')
    }


    В папку build не нужно добавлять изображения вручную, воспользуйтесь file-loader или url-loader, они позволяют настроить и путь, например папка img внутри build, пример:
    {
        test: /\.(png|jpg|jpeg|gif|svg)$/,
        loader:'file',
        query: {
            name: 'img/[name].[ext]'
        }
    }
    Ответ написан
    Комментировать
  • Как калькулятор, который написан на JQuery, засунуть в качестве компонента React?

    @SuperOleg39ru
    Front-end разработчик
    Если честно, не уверен что вы целенаправленно изучали реакт.
    Рекомендую потратить немного времени на этот курс: https://maxfarseer.gitbooks.io/react-course-ru/content/

    Небольшой пример на ES5:
    Для ограничения ввода, к примеру, возьмем готовый плагин react-numeric-input
    var NumericInput = require('react-numeric-input');
    
    var Calculator = React.createClass({
      getInitialState: function() {
        return {
          price: 0,
          offer: 0,
          result: 0
        };
      },
      caclResult: function() {
        this.setState({result: this.state.price - this.state.offer});
      },
      render: function() {
        return (
          <div className='calculator'>
            <NumericInput min={0} max={100} value={this.state.price} onChange={this.caclResult} />
            <NumericInput min={0} max={100} value={this.state.offer} onChange={this.caclResult} />
            <span>Итого: {this.state.result}</span>
          </div>
        )
      }
    });
    Ответ написан
    4 комментария
  • Как повторно отправить не успешные запросы?

    @SuperOleg39ru
    Front-end разработчик
    Добрый день!

    Вкратце, как решал эту проблему:
    Отдельный сервис занимается сохранением и обновлением токена, назовем его Session.
    В interceptors фазе request вы все делаете верно, это добавляет токен на каждый запрос.

    Переходим к фазе responseError:
    1) Определяем необходимые тип ошибки
    2) Можно ограничить количество повторных запросов, и редиректить на login page (тут свой нюанс, надо обнулять счетчик в фазе response - успешный ответ)
    3) Отправляем запрос на обновление токена
    4) При успехе, вызываем сервис $http с параметрами этого запроса

    Пример кода:
    responseError: function(rejection) {
      ...
    
      if (tokenError) {
        return Session.refreshToken().then(function() {
            return $http(rejection.config); // Повторяем запрос, когда получили новый токен
        });
      }
    
      return $q.reject(rejection);
    }
    Ответ написан
    4 комментария
  • Почему не могу обновить данные при получения события?

    @SuperOleg39ru
    Front-end разработчик
    Добрый день!

    Broadcast вызывается до успешного добавления данных, поэтому его надо перенести в then. Попробуйте так:
    $scope.addDb = function (name) {
            NetFactory.addDb(name).then(
                function (data) {
                    $scope.message = data;
                    $rootScope.$broadcast('db:change');
                }
            );
    };
    Ответ написан
    3 комментария