• Как отследить когда Angular отрендерил представление?

    @Faliah
    По-моему Директивы и их функция link созданы именно для этих вещей. Если же вы используете компоненты, то у них есть lifecycle метод $postLink()
    Ответ написан
    Комментировать
  • Первое приложение на Angular, как его осилить?

    @Faliah
    Если сам опросник у вас будет храниться в памяти, то можете делать хоть на github pages. С другой стороны - применять SPA фреймворк без работы с бэкендом какого-либо вида (socket, rest) это как из пушки по воробьям. Для отрисовки и связывания компонентов вам и голого React хватило бы.

    Но ответ на ваш вопрос - не нужна
    Ответ написан
  • Как составить глубокое вложения классов в javascript?

    @Faliah
    Не совсем понял в чём вопрос. Если под "глубокое вложение классов" вы подразумеваете то, что функции-конструкторы у вас являются свойствами объектов, вложенных в другие объекты, то у вас ничего не поменяется:
    let Root = {};
    Root.Child = {};
    
    class MyClass {
      constructor(prop1, prop2) {
        this.prop1 = prop1;
        this.prop2 = prop2;
      }
    }
    
    Root.Child.MyClass = MyClass;
    
    var instance = new Root.Child.MyClass('super', 'great');
    console.log(instance);


    Если же вы имели в виду сильно вложенное наследование RootClass -> ChildClass -> ChildOfChildClass. То хотелось бы от этого предостеречь и дать несколько ссылок на английские ресурсы. Лучше сразу приучаться делать правильно (по-крайней мере так принято):

    Yuotube ролик - Composition over inheritance
    Prefer composition over inheritance
    Common Misconceptions About Inheritance in JavaScript
    3 Different Kinds of Prototypal Inheritance: ES6+ ...
    The Open Minded Explorer’s Guide to Object Composition
    The Two Pillars of JavaScript
    Ответ написан
    Комментировать
  • Есть ли простой движок для кастомных географических карт?

    @Faliah
    Есть смысл использовать популярный и поддерживаемый LeafletJS. Очень мощная библиотека, разобравшись, с которой, о проблемах связанных с картографией можно забыть
    Ответ написан
    2 комментария
  • Как причесать код?

    @Faliah
    Упростить можно всё, что угодно, просто взшлянув на проблему с другой стороны. Есть несколько вопросов по коду:
    3182804ed7444150bdab28a4ac0e5588.png

    1) В функцию redis.hmget вы передаёте две строки 'level' и code lang="javascript">'language' (в красных прямоугольниках). Нельзя ли избавиться от них, ведь, по сути это константы? То же самое касается их аналогов в красных прямоугольниках со скруглёнными уголками. Если в каждую функцию redis.hmset нужно обязательно передать 'level', то, на мой взгляд полезно было бы сделать обёртку
    function memoizeArguments() {
      
      const memoizeArgs = Array.from(arguments);
      
      return function(fun) {
        return function() {
          fun.apply(null, memoizeArgs.concat(Array.from(arguments).join()));
        }
      }
      
    }
    
    app.on('message', msg => {
      
      const telegramID = msg.from.id,
            encodedID = `id${telegramID}`,
            text = msg.text;
    
      // Сохраняем аргументы, чтобы упростить сигнатуры вызовов, создаём обертки с закэшированными аргументами
      const withId = memoizeArguments(telegramID);
      const appSendMessage = withId(app.sendMessage);
      
      const withEncodedIdAndLevel = memoizeArguments(encodedID, 'level');
      const redisHmSet = withIdAndLevel(redis.hmset);
      
      
    
      redis.hmget(encodedID, 'level', 'language', (err, res) => {
        
        let sendMessageArgs = null;
        let redisHmSetArgs = null;
        
        switch (res[0]) {
          case 'language':
            sendMessageArgs = message[text].languageGood;
            redisHmSetArgs = ['user_name', 'language', msg.text];
          break;
    
          case 'user_name':
            sendMessageArgs = [message[res[1]].nameGood, options];
            redisHmSetArgs = ['user_name', text, 'change_services']; // тут парамет 'level' передастся 2м аругментом, а не 4м
          break;
    
          case 'change_services':
            
            switch(text) {
                
              case 'some text':
                sendMessageArgs = message[res[1]].flpPhone;
                redisHmSetArgs = ['flp', 'sublevel', 'phone'];
                break;
    
              case 'another text':
                redisHmSetArgs = 'ooo';
                break;  
                
              case 'other':
                redisHmSetArgs = 'reg';
                break; 
                
              default:
                sendMessageArgs = message[res[1]].changeServicesBad;
                break;
            }
           
          break;
        }
    
        if (sendMessageArgs) appSendMessage(sendMessageArgs);
        if (redisHmSetArgs) redisHmSet(redisHmSetArgs);
        
      });
    });


    Вообще говоря логику фомирования массивов с аргументами тоже можно упростить и сделать единообразной, либо делать функции app.sendMessage и redis.hmset менее полиморфными - в разных вызовах передается разное число аргументов и иногда в разном порядке. Это сложно для понимания
    Ответ написан
    Комментировать
  • Как изменить грамотно код?

    @Faliah
    Если objectPath.del удаляет данные из obj_str, то измените код так, чтобы фукнция objectPath.del возвращала результирующий объект:
    objectPath.del = (obj, level) => {
      // тут логика удаления данных по уровню
    
      return updated_obj; // возвращаем измененный объект
    }


    После этого в коде можно пользоваться именно как вы хотели
    case DELETE_STRUCTURE_COUPLE:
          return {
            ...state,
            structure: objectPath.del(state.structure, action.level)
          };
    Ответ написан
    Комментировать
  • Как обьеденить AJAX события в условие(if)?

    @Faliah
    Вот тут описан способ
    $(document).bind('ready ajaxComplete', function(){
      // Your code here
     })
    Ответ написан
    Комментировать
  • Почему не работает скрипт?

    @Faliah
    Не могли бы вы уточнить логику запуска отсчета и отображения прогресса?

    Чтобы изменять значение атрибута 'percent' по ходу изменения значения счетчика, используйте такой код:
    $('.elem-exp .js-svg-bar').countTo({
      to: 70,
      speed: 1000,
      onUpdate: function(value) {
        $(this).attr({'percent': value});
      }
    });
    Ответ написан
    7 комментариев
  • Почему не увеличивается style.width?

    @Faliah
    Вот так работает. Проблема в том, что вы пытались работать с progressBar.style.width как с числом, но оно является строкой, при этом DOM API не дает устанавливать некорректное значение этого атрибута, которое, с каждой итерацией у вас представляло бы вот такую запись "2%4%6%" и т.д
    Ответ написан
    1 комментарий
  • Как наложить картинку на первую букву?

    @Faliah
    А что конкретно вы подразумеваете под "не будет адаптивно"? position: absolute Выравнивает элемент относительно ближайшего родительского блока, у которого position: relative. Если таких элементов нет, то им становится body.
    Вот быстрая реализация: Выглядит не плохо

    Её минусы в том, что размеры статические, но если поиграть с процентами, em или rem, то можно сделать полностью динамические размеры.

    Быстро сделал обновлённую версию через rem - при изменении font-size у html картинка и текст довольно хорошо подстраиваются, не разъезжаясь
    Ответ написан
    6 комментариев
  • Как скрывать именно верхний элемент?

    @Faliah
    Примерно так можно: тыц

    Код, естественно, можно оптимизировать под реальную разметку и функционал
    Ответ написан
    6 комментариев
  • Как повесить событие на элемент с классом?

    @Faliah
    Можно воспользоваться "делегацией" событий:
    (function (document) {
    
      var selectedItem = null;
    
      document.querySelector('ul')
        .addEventListener('click', function(e) {
          if (selectedItem) {
        	  selectedItem.className = selectedItem.className.replace(' selected', '');
          }
        
          if (e.target.className.indexOf('selected') == -1) {
        	  e.target.className += ' selected';
          }   
          selectedItem = e.target;
        });
    })(document);


    Смотреть на jsfiddle
    Ответ написан
    Комментировать
  • Почему promise.catch() не перехватывает ошибку?

    @Faliah
    Желательно указать каким драйвером, для какой БД вы пользуетесь. Мне странно видеть в коде на node.js блокирующий запрос к БД, когда почти для любых i/o операций используются неблокирующие вызовы с коллбэками. Вполне возможно, что вам нужно вручную выбросить исколючение в коллбэке/зареджектить промис при наличии err, в вызове коллбэка после запроса
    Ответ написан
    Комментировать
  • Как запустить async/await в браузере?

    @Faliah
    В каком смысле код для Node.js?

    Вы можете переписать эту функцию через Promise:

    function getMovieAsync() { 
      fetch('https://www.omdbapi.com/?t=The Matrix')
        .then(response => response.json())
        .then(data => { console.log(data.Title) });
    }
    
    getMovieAsync();
    Ответ написан
    1 комментарий
  • Ruby: "Дорожная карта", пoмoгите составить?

    @Faliah
    Сегодня на хабре опубликовали статью. Ознакомьтесь с ней и ссылками на другие материалы, которые в ней есть. Там все довольно четко расписано. Просто выпишите себе список сущностей, которые перечисляет автор "миграции", "модели", "роуты", "вьюхи". Все это есть на официальном сайте с туториалом по Rails. Изучите. Попробуйте воспроизвести то, что делал автор. Уверен, если вы будете способны реализовать что-то похожее на написанный автором форум, то без труда найдете себе заказчиков. Ну и будете готовы глубже погружаться в "тему"

    И да, без JS будет туго, так что его обязательно в список
    Ответ написан
    1 комментарий
  • Вычисление ширины: как избежать повтора кода?

    @Faliah
    На сколько я понимаю, переменная newwidth имеет одно и то же значение в коллбэке onscroll и во внешнем, по отношению к этому коллбэку, коде, где она объявляется и инициализируется под переменной block. Если это так, то вы можете убрать объявление этой переменной из коллбэка, т.к. код, находящийся в нём имеет доступ к внешнему контексту (т.к. функции в JS являются замыканиями) и может обращаться к переменной newwidth, объявленной там:
    function getTopOffset(e) { 
      var y = 0;
      do { y += e.offsetTop; } while (e = e.offsetParent);
      return y;
    }
    var block = document.getElementById('SecondBlock');
    var newwidth = 'width: ' + (document.body.clientWidth - document.getElementById('MainBlock').offsetWidth - 64) / 2 + 'px';
    block.setAttribute( 'style', newwidth );
    if ( null != block ) {
      var topPos = getTopOffset( block );
      window.onscroll = function() {
        var newcss = (topPos < window.pageYOffset) ? 'top: 16px; position: fixed;' : '';
        block.setAttribute( 'style', newcss + '' + newwidth);
      }
    }
    Ответ написан
    Комментировать
  • Array.prototype.concat([1], [2]) //-> [1,2] -- Почему нет ошибки?

    @Faliah
    Ответ кроется в значении Array.ptotype, которым является []. Поэтому в данном случае происходит конкатенация 3х массивов - [], [1] и [2]. Никакой ошибки быть и не должно
    Ответ написан
  • Как вызвать Javascript событие для виджета "Поделиться" от Yandex?

    @Faliah
    Все прекрасно работает даже простым ctrl-c+ctrl-v
    Скопировано из официальной документации

    По сути:
    1. кидаете на страницу элемент, предположим
      <div id="ya_share" class="ya-share2" data-services="vkontakte,twitter,facebook,gplus" data-counter></div>

    2. инициализируете виджет:
      Ya.share2('#ya_share', {
          hooks: {
              onready: function () {
                  alert('блок инициализирован');
              },
      
              onshare: function (name) {
                  alert('нажата кнопка' + name);
              }
          }
      });

    3. ...Profit
    Ответ написан
    5 комментариев
  • Как вывести нужные значения?

    @Faliah
    Вы пытались сравнить строковые значения,xdata и today как две даты, естественно поведение было не тем, как ожидалось.

    Нужно сравнивать два объекта типа Date: https://jsfiddle.net/t1fetkr5/33/
    Ответ написан
    1 комментарий
  • Как сделать replace в javascript по маске?

    @Faliah
    Понятно, что совершенно универсальное выражение написать невозможно :) Но примерно так можно это сделать для такого формата и номеров с различной длиной кода (+7, +34, да сколько угодно в общем-то):

    Написано на ES6, но изменения для ES5 минимальны

    "use strict";
    
    const number = "39091111111"; //тут неотформатированное значение
    const pattern = new RegExp(`(^\\d{${number.length % 10}})(\\d{3})(\\d{3})(\\d{2})(\\d{2}$)`);
    const formattedNumber = number.replace(pattern, '+$1($2)$3-$4-$5');
    console.log(formattedNumber); //выведет +3(909)111-11-11
    Ответ написан
    Комментировать