Ответы пользователя по тегу JavaScript
  • Какое регулярное выражение использовать?

    @SuperOleg39ru
    Front-end разработчик
    /\|([^|]*)\$k/g

    Нужный текст окажется в группе
    Ответ написан
    Комментировать
  • Функция connect() Redux, как правильно использовать?

    @SuperOleg39ru
    Front-end разработчик
    Множество connect компонентов, которые передают из store минимально необходимое количество данных - это верный подход, в таком случае компонент, обернутый в connect, будет обновляться только тогда, когда изменились реальные данные, от которых он зависит.

    По вашей проблеме:

    Представим, что в store у вас есть 2 свойства:
    1) options - массив строк для селекта
    2) selectedOption - выбранная строка (пустая по дефолту)

    И например одно действие - selectOption(option), для обновления selectedOption в store.

    Далее условные обернутые компоненты:
    // Ваш сайдбар обновится при каждом изменении selectedOption
    connect((state, ownProps) => ({ selectedOption: state.selectedOption }))(SidebarComponent)
    
    // Ваш селект обновляется в зависимости от изменения обоих свойств,
    // и используя свойство onSelect может обновить selectedOption самостоятельно
    connect(
      (state, ownProps) => ({ options: state.options, selectedOption: state.selectedOption }),
      (dispatch, ownProps) => ({ onSelect: (value) => dispatch(selectOption(value)) })
    )(SelectComponent)
    Ответ написан
  • Как добавить минимизацию css в webpack?

    @SuperOleg39ru
    Front-end разработчик
    Когда вы добавляете стили в качестве entry, они оборачиваются в js скрипт, который просто вставляет эти стили на страницу, при загрузке.

    Обычный кейс для создания отдельного css бандла:

    // в вашем './src/app.js'
    import './styles/main.sass';
    
    // в конфиге вебпака все надо упростить
    // entry
    {
      app: './src/app.js',
    }
    // module.rules
    {
      test: /\.sass$/,
      use: ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: [
          'css-loader',
          'sass-loader'
        ]
      })
    }
    // plugins
    new ExtractTextPlugin('styles/[name].css')


    Название entry мы меняем, для читаемости, что бы не делать всякие bundle.bundle.js или bundle.min.js,
    Ваши стили получат такое же имя, как и основной js файл - итого app.min.js и app.min.css
    HtmlWebpackPlugin автоматически подтянет ссылки на эти файлы.
    Ответ написан
    1 комментарий
  • Как решить несовпадение сигнатур при использовании сторонних библиотек?

    @SuperOleg39ru
    Front-end разработчик
    Декларация метода shuffle:
    shuffle<T>(list: _.Collection<T>): T[];

    Возможно, свойство класса this.proposed_options не типизировано как Syllable.

    Перепишите вручную, но используя generic:
    _.shuffle<Syllable>(this.proposed_options)
    Ответ написан
    Комментировать
  • Как реализовать этот ползунок?

    @SuperOleg39ru
    Front-end разработчик
    1) Треугольная форма прогресс-бара делается бордерами: https://css-tricks.com/snippets/css/css-triangle/

    2) Движение ползунков, ключевые моменты:
    Событие mousedown вы отслеживаете на ползунке либо на прогресс-баре.
    Внутри обработки mousedown вешаете события mousemove и mouseup на document или window (не забудьте их убрать по mouseup)

    Во время mousemove вычисляете положение курсора относительно левого края слайдера (например event.clientX - sliderElement.getBoundingClientRect().left).

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

    Еще, для адаптивности, желательно все из пикселей в % переводить
    Ответ написан
    Комментировать
  • Как вернуть контекст в данном случае?

    @SuperOleg39ru
    Front-end разработчик
    1 вариант - использовать стрелочные функции:

    method(function() {
    ...
    });
    
    // заменить на 
    method(() => {
    ...
    })


    2 вариант - привязать контекст к переменной:

    const that = this;
    that.context;


    Почитайте это
    Ответ написан
    2 комментария
  • Как протестить то, что случится после нажатия кнопки в React(Jest, enzyme)?

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

    Разделяйте тестирование частей React + Redux приложения:

    1) Отдельно reducer и соответствующие actions, что делать очень просто, так как это чистые функции и простые объекты.

    2) Отдельно react компонент, и вы должны проверить только то, что при simulate('click') вызовется соответствующий обработчик.
    Пример:
    const props = {
        onClick: jest.fn()
    };
    let component;
    
    beforeEach(() => {
        component = enzyme.shallow(<Button {...props} />);
    });
    
    it('срабатывает событие onClick', () => {
        field.simulate('click');
        expect(props.onClick).toHaveBeenCalled();
    });


    Если вам нужно проверить, отреагировал ли компонент на изменение его свойств, то вы меняете его свойства напрямую через component.setProps({ key: 'value' });
    Ответ написан
    Комментировать
  • Почему webpack-dev-server не отдаёт бандл для index.hmtl?

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

    Надо именно такой адрес - добавьте output.publicPath: '/bundles/'

    Лучше используйте HtmlWebpackPlugin, он сам создаст index.html + добавит ваш index.js на страницу.

    В данный момент ваш index.js находиться виртуально в одной директории с index.html.
    Ответ написан
    Комментировать
  • Angular 1.6.4 $watchGroup возвращает пустые строки для старых значений. Не пойму в чём дело?

    @SuperOleg39ru
    Front-end разработчик
    Рекомендую вам отказаться от $watchGroup и $watch, вместо этого на инпуты добавьте ng-change, и уже в функциях-обработчиках делайте все что вам угодно.

    Причины:
    1) Полностью контролируете процесс
    2) Нет потери производительности из за watch'еров
    Ответ написан
  • [code-review] JS галерея, какие замечания?

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

    1) Для удобства оформите библиотеку как npm пакет.
    И что бы этот пакет можно было использовать разными системами сборки, можно использовать формат определения модуля UMD

    2) При создании экземпляра const gallery = new Gallery({}) - неплохо бы иметь доступ к управлению галереей через JS, например:
    gallery.pause();
    gallery.next();


    Возможно вам захочется добавлять слайды на лету, это тоже отдельный метод.

    3) Так же, можно добавить изменение настроек на лету, gallery.setOptions({})

    В связи с этим можно сделать вывод, что нужен более объекто-ориентированный код, то есть вы создаете класс Gallery, который имеет методы для управления, сохраняет свойства себе в контекст (this), например:

    var defaultOptions = {
      ...
    }
    
    privateMethod() {
      ...
    }
    
    function Gallery(options) {
      this.options = extend(defaultOptions, options);
      this.interval = this.createInterval();
      ...
    }
    
    Gallery.prototype.init = function() {
      ...
    }
    
    Gallery.prototype.next = function() {
      ...
    }
    
    Gallery.prototype.createInterval= function() {
      ...
    }
    
    function extend(a, b) {
      ...
    }


    То есть, всю логику вы разделяете на отдельные функции, которые являются методами класса Gallery, если нужен публичный доступ к этой логике, либо выносите эти методы и свойства наружу, если их нельзя менять пользователям.
    Ответ написан
    3 комментария
  • Как ставить темы для Ангуляра?

    @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 использовать не обязательно, замедляет начало сборки.
    Ответ написан
    Комментировать
  • Делаю директиву Angular вида autocomplete. Как правильно передавать параметры?

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

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

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