Задать вопрос
  • Почему не отображается дочерний компонент?

    0xD34F
    @0xD34F
    Нет у вас в компоненте recepies одноимённого массива, он находится в recipie-list. Очевидно, этот массив надо перенести в recepies (тогда его можно будет обойти с помощью ngfor для создания экземпляров recipies-detail), а в recipie-list передавать его как параметр.
    Ответ написан
    Комментировать
  • Как в react js по нажатию tab установить в нужное место каретку input-а?

    0xD34F
    @0xD34F Куратор тега React
    onKeyDown = e => {
      if (e.key === 'Tab') {
        e.preventDefault();
    
        const
          input = e.target,
          str = input.value,
          currPos = input.selectionStart,
          wordEnd = str.slice(currPos).search(/[^\w]/);
    
        let pos = str.slice(currPos + wordEnd).search(/[^\s]/);
        if (pos) {
          pos += currPos + wordEnd;
        }
        if (pos === currPos) {
          pos = 0;
        }
    
        input.setSelectionRange(pos, pos);
      }
    }

    <input value={this.state.str} onKeyDown={this.onKeyDown} />

    https://jsfiddle.net/acvjhxyt/
    Ответ написан
    Комментировать
  • Как сделать. чтобы :after был под box-shadow?

    0xD34F
    @0xD34F Куратор тега CSS
    задайте ему отрицательный z-index
    Ответ написан
    Комментировать
  • Взаимодействие Vue компонентов: Property or method "updatebalance" is not defined?

    0xD34F
    @0xD34F Куратор тега Vue.js
    <balancelabel @updbalance="updatebalance"></balancelabel>

    А зачем здесь обработчик события? Вы это событие обрабатываете внутри компонента, emit не делаете... Может его, ну не знаю, УБРАТЬ?!
    Ответ написан
    Комментировать
  • Как сделать активным элемент по нажатию на него?

    0xD34F
    @0xD34F
    Вам тут не нужен jquery, если уже используете angular. Добавляете в компонент свойство, которое будет содержать ссылку на выбранный объект и устанавливаете его значение по клику. Добавляете элементам класс, если выбранный объект совпадает с текущим:

    <div
      *ngFor="let user of users"
      [class]="active === user ? 'active' : ''"
      (click)="active = user"
    >

    например
    Ответ написан
    Комментировать
  • Как отслеживать любые изменения в объекте data?

    0xD34F
    @0xD34F Куратор тега Vue.js
    watch срабатывает тогда когда мне не надо

    Ну так и включайте наблюдение только тогда, когда вам это нужно. Как это сделать, можете прочесть в документации.

    вотчер возвращает оба одинаковых значения

    Что естественно - от того, что вы изменили какое-то из свойств объекта, объект не заменит себя своей копией. Хотите, чтобы старое и новое значение были разными - заменяйте объект целиком.
    Ответ написан
    1 комментарий
  • Как взять рандомный элемент массива?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Как извлечь случайный элемент массивоподобного объекта:

    const random = arr => arr[Math.random() * arr.length | 0];

    Извлекаем:

    // одно значение
    const randomName = random(arr_names);
    
    // или сразу несколько
    const randomNames = Array.from(
      { length: 5 },
      random.bind(null, arr_names)
    );
    
    // работать можно не только с массивами, но и,
    // например, со строками, NodeList или HTMLCollection
    const randomChar = random('abcdefg');
    const randomSpan = random(document.querySelectorAll('span'));
    const randomImage = random(document.images);
    Ответ написан
    Комментировать
  • Как найти родителя элемента с проверкой наличия класса?

    0xD34F
    @0xD34F Куратор тега JavaScript
    $(elem).closest('.parent').addClass('active_list')
    Ответ написан
    3 комментария
  • Почему scrollHeight равен undefined?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Потому что в jquery ничего такого нет, это свойство элемента. Которое получить можно так:

    $('#text-column').prop('scrollHeight')
    // или
    $('#text-column').get(0).scrollHeight
    // или
    $('#text-column')[0].scrollHeight
    Ответ написан
  • Как в jquery вывести именно тот data атрибут по которому щелкнули?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Где и что надо получить:

    const containerSelector = '.va-city-list';
    const key = 'city';
    const attr = `data-${key}`;
    const attrSelector = `[${attr}]`;
    const itemSelector = `${containerSelector} ${attrSelector}`;

    Как достать из элемента значение атрибута:

    const getVal = el => $(el).data(key);
    // или
    const getVal = el => $(el).attr(attr);
    // или
    const getVal = el => el.dataset[key];
    // или
    const getVal = el => el.getAttribute(attr);
    // или
    const getVal = el => el.attributes[attr].value;

    Слушать клики можно непосредственно на элементах, содержащих атрибуты:

    $(itemSelector).click(e => console.log(getVal(e.currentTarget)));
    
    // или
    
    document.querySelectorAll(itemSelector).forEach(function(n) {
      n.addEventListener('click', this);
    }, e => console.log(getVal(e.currentTarget)));

    Или можно назначить обработчик клика один раз - общему предку элементов:

    $(containerSelector).on('click', attrSelector, function() {
      console.log(getVal(this));
    });
    
    // или
    
    document.querySelector(containerSelector).addEventListener('click', e => {
      const el = e.target.closest(itemSelector);
      if (el) {
        console.log(getVal(el));
      }
    });
    Ответ написан
    Комментировать
  • Как упростить подсчёт нажатий кнопок?

    0xD34F
    @0xD34F Куратор тега JavaScript
    А зачем двигаться "пошагово"? Известны же координаты кнопок - можно вычитать одни из других, и сразу получать количество шагов:

    const keyboard = [
      'abcde123',
      'fghij456',
      'klmno789',
      'pqrst.@0',
      'uvwxyz_/',
    ].reduce((acc, [...row], iRow) => {
      row.forEach((key, iCol) => acc[key] = [ iRow, iCol ]);
      return acc;
    }, {});
    
    function tvRemote(word) {
      let steps = word.length;
      let prev = [ 0, 0 ];
    
      for (const n of word) {
        const curr = keyboard[n];
        steps += Math.abs(prev[0] - curr[0]) + Math.abs(prev[1] - curr[1]);
        prev = curr;
      }
    
      return steps;
    }
    Ответ написан
    2 комментария
  • Vue - валидация объекта в props?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Валидация входных параметров

    UPD. Вынесено из комментариев.

    Решение через фунцию-валидатор я видел, но мне оно не кажется оптимальным для объектов. По крайней мере в React это намного короче и наляднее.

    Возможно во Vue есть аналог?

    Из коробки нет (следует отметить, что в React тоже - начиная с версии 15.5 React.PropTypes является устаревшим, и вместо него следует использовать prop-types). Можете сделать класс и передавать в props конструктор для проверки, что переданный параметр является экземпляром класса. Или используйте сторонние библиотеки, например - там аналог PropTypes.shape есть.
    Ответ написан
  • Почему выдает ошибку "Cannot read property of undefined" при попытке обратиться к свойствам PropTypes?

    0xD34F
    @0xD34F Куратор тега React
    "react": "^16.4.0",

    import React, { Component, PropTypes } from 'react';

    Понятно. Открываем документацию, и видим, что

    Note:
    React.PropTypes has moved into a different package since React v15.5. Please use the prop-types library instead.
    Ответ написан
    2 комментария
  • Как в цикле создавать элементы?

    0xD34F
    @0xD34F Куратор тега React
    Array.from({ length: 5 }, () => <Text>hello, world!!</Text>)
    Ответ написан
    Комментировать
  • Как сделать чтобы модалка работала для всех кнопок?

    0xD34F
    @0xD34F Куратор тега JavaScript
    .modal.opened {
      display: block;
    }

    const modal = document.querySelector('.modal');
    const close = modal.querySelector('.close');
    const toggleModal = state => modal.classList.toggle('opened', state);
    const buttonSelector = 'button';

    Вариант раз - делаем делегированный обработчик клика, в котором проверяем, где случилось событие. Если кнопка - значит, надо открыть окно. Если корневой элемент окна или .close - наоборот, закрыть:

    document.addEventListener('click', ({ target: t }) => {
      if (t === modal || t === close) {
        toggleModal(false);
      } else if (t.matches(buttonSelector)) {
        toggleModal(true);
      }
    });

    Вариант два - назначаем обработчики непосредственно тем элементам, которые пользователь должен кликать:

    [ modal, close ].forEach(function(n) {
      n.addEventListener('click', this);
    }, e => e.target === e.currentTarget && toggleModal(false));
    
    document.querySelectorAll(buttonSelector).forEach(function(n) {
      n.addEventListener('click', this);
    }, toggleModal.bind(null, true));
    Ответ написан
    1 комментарий
  • Почему шина событий не слышит событие?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Возможная причина номер раз - в тот момент, когда вы делаете emit события, отсутствует экземпляр компонента, где вы пытаетесь его слушать.

    Возможная причина номер два:

    bus.$off('selectedCompanies')

    Толково придумано. Давайте представим, что создаётся два... нет, лучше пять экземпляров компонента. Затем один удаляется. Вопрос - сколько после этого останется обработчиков события selectedCompanies? Думаете, что четыре? А вот и нет - ни одного. Надо всё-таки указывать, какой именно обработчик вы удаляете.

    Наконец, возможная причина номер три:

    Есть 2 независимы страницы.

    Очень надеюсь, вы подразумеваете не разные вкладки/окна браузера.
    Если всё-таки да...

    ...ну, поздравляю - чего-то вы в этой жизни не понимаете, от слова совсем. Нет реакции на событие потому, что шин у вас две - и ничего они друг о друге не знают. В этом случае вам нужна не шина, а надо как-то пересылать информацию между вкладками. Для этого можно использовать localStorage (есть плагины для vuex под это дело, можете погуглить), или BroadcastChannel.
    Ответ написан
  • Почему при поиске вылезает TypeError: Cannot read property 'toString' of null?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Какое-то из свойств объекта оказалось null'ом. Почему бы не добавить проверку перед toString'ом - что именно вы собираетесь преобразовывать? Может и не надо перегонять null'ы в строки, может, в этом случае результат поиска сразу отрицательный должен быть. Ну или преобразовывайте в строку как-нибудь иначе, варианты разные есть: ('' + m) или `${m}` или String(m).

    А вообще, вы конечно поторопились вот так в лоб использовать первый попавшийся код. Вон, у вас там ещё и вложенные объекты есть, по их свойствам поиск корректно работать не будет (т.к. дефолтное строковое представление объекта - это '[object Object]') - об этом вы подумали? Нет, точно надо проверять, что за значение:

    return this.sortedTokens_VMP.filter(n => Object.values(n).some(m => {
      if (m instanceof Object) {
        // проверяем объект, возможно, стоит сделать какую-нибудь рекурсивную функцию под это дело
      } else if (typeof m === 'number') {
        // а вдруг числа надо обрабатывать иначе, чем строки
      } else {
        // какая-то дефолтная проверка значения
      }
    }));

    UPD. А сортировка, сортировка-то - тоже ведь ерунда получится при работе с null'ами и вложенными свойствами.

    Вот как всё будет:

    Рекурсивная функция, которая проверяет, есть ли где во вложенных объектах указанная строка:

    const includes = (obj, str) => Object
      .values(obj)
      .some(n => n instanceof Object
        ? includes(n, str)
        : `${n}`.toLowerCase().includes(str)
      );

    Используем её внутри вычисляемого свойства, представляющего отфильтрованные данные:

    filteredTokens_VMP() {
      const s = this.search.toLowerCase();
      return this.sortedTokens_VMP.filter(n => includes(n, s));
    },

    Функция, извлекающая вложенное значение по строке, где ключи разделены точками:

    const getNested = (root, path) => path
      .split('.')
      .reduce((p, c) => p != null ? p[c] : p, root);

    Используем её в вычисляемом свойстве, представляющем отсортированные данные, если попадается nullish значение, будем загонять соответствующий элемент в конец:

    sortedTokens_VMP() {
      const reverse = this.sort.reverse ? -1 : 1;
      return this.tokens_VMP
        .map(n => [ getNested(n, this.sort.key), n ])
        .sort(([a], [b]) => reverse * (
          a == null ?  Infinity :
          b == null ? -Infinity :
          a < b     ?        -1 :
          a > b     ?         1 :
                              0
        ))
        .map(n => n[1]);
    },
    Ответ написан
  • Как организовать поиск во Vue?

    0xD34F
    @0xD34F Куратор тега Vue.js
    вот пример - https://codepen.io/pespantelis/pen/ojwgPB?editors=1010,
    но здесь используется версия vue/0.12.16/vue.min.js

    Нет проблем переписать с использованием актуальной версии vue.
    Ответ написан
    1 комментарий