• Как проинспектировать динамически добавляемый элемент?

    @antonwx
    Откройте консоль разработчика, начните перетаскивать элемент, и когда появится галочка, нажмите F8. Произойдёт "заморозка" состояния страницы. И теперь можете инспектировать.
    Ответ написан
    1 комментарий
  • Как только закрыть попап при нажатии кнопки "назад"?

    nuykon
    @nuykon
    Full Stack Developer
    history.scrollRestoration = 'manual';
    еще вариант
    history.pushState({popup: true, scrollTop: 0}, 'popup');
    Ответ написан
    1 комментарий
  • Почему не работает lodash debounce в vue?

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

    Разумеется, всё работает. Между "не работает" и "работает не так, как бы мне хотелось" существенная разница. Допускаю, что для вас она трудноуловима, но она всё-таки есть. Попытайтесь её осознать.

    test: function() {
        _.debounce(function() {
                console.log('test222');
            }, 500);
    }

    Надо полагать, в debounce должен был быть обёрнут сам метод:

    test: _.debounce(function() {
      console.log('test222');
    }, 500)
    Ответ написан
    2 комментария
  • Как затирать цифру 8 при вводе в инпут с маской?

    ReaverJS
    @ReaverJS

    Но прям вообще не юзер френдли.

    Лучше через dispatch - подстраивать маску под +7 или 8 соответственно.
    Ответ написан
    5 комментариев
  • Как правильно подключить vuejs?

    alex-1917
    @alex-1917
    Если ответ помог, отметь решением
    v-cloak ПЛЮС вот такой html
    <div id="app"></div>

    т.е. абсолютно чистый голый контейнер.

    80% так называемых видео и не только но гайдов предлагают туда что-то да запихнуть, это все будет безжалостно отображаться до момента инициализации китайского поделия.
    Ответ написан
    1 комментарий
  • Vue-slick, почему клонированные слайды не реагируют на @click?

    0xD34F
    @0xD34F Куратор тега Vue.js
    Vue-slick - это не более чем обёртка над обычным slick'ом, так что vue про клонированные слайды ничего не знает, создаёт их не он. Соответственно, и обработчикам событий, добавляемым с помощью vue, там взяться неоткуда.

    Делегируйте обработку событий - обработчик вешается на корневой элемент слайдера, был ли клик выполнен по слайду определяется по наличию класса slick-slide у предков целевого элемента, номер слайда можно определить через атрибут data-slick-index (или можете назначать слайдам какие-то свои классы/атрибуты для выяснения, где был произведён клик).

    https://codesandbox.io/s/vue-template-3d5h7
    Ответ написан
    Комментировать
  • Как наказать нерасплатившегося за сайт заказчика?

    @boodda
    Вариант изощерённой мести все таки имеется, внести бекдор типа $a($b) в несколько мест кода, и подождать месяцок, пока бэкапы станут забэкдорены, ну а потом поднять на своём сервере его сайт, а у него поставить на все 301 редирект, сайт свой зарегать в яндекс мастере, и гугл мастере, а на его серваке через пару месяцев все удалить можно все, и вы владелец трафа )
    Ответ написан
    Комментировать
  • Как кратко записать в строку все ключи с непустым значение объекта?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Object.entries(props).filter(n => n[1]).map(n => n[0]).join(',')

    или

    `${Object.entries(props).reduce((acc, [ k, v ]) => (v && acc.push(k), acc), [])}`

    или

    Object.entries(props).map(n => n[1] && n[0]).filter(Boolean).toString()

    или

    '' + Object.keys(props).reduce((acc, n) => props[n] ? [ ...acc, n ] : acc, [])

    или

    String(Object.keys(props).filter(n => props[n]))
    Ответ написан
    2 комментария
  • Получение данных по публичному API через Axios во Vue?

    yarkov
    @yarkov Куратор тега JavaScript
    Проект "Жизнь после смерти" - lifeafterdeath.ru
    Может не params, а data? Вы же POST оправляете.
    Или так вообще (не помню как в axios верно:
    {
         "period": 0,
         "date": "2019-03-05T15:12:13.319Z"
     }
    Ответ написан
    Комментировать
  • Как правильно передавать данные через сервис Angular?

    search
    @search
    мама говорит что я особенный
    Для вашего случая существует лучшая практика: так называемые умные и глупые компоненты: https://medium.com/@dan_abramov/smart-and-dumb-com... (это оригинальная статья от автора реакта, но в ангуляре принципы такие же)

    В нашем случае компоненты search и result - глупые компоненты, которые только и делают, что возвращают строку ввода (search) и отображают данные (result). Так же у нас имеется умный компонент searchResults, который знает как отреагировать на данные из search и правильно отобразить result.

    Search и Result ничего не должны знать об HttpService. Он в них не инжектится.

    SearchComponent:

    import { Component, EventEmitter, Output } from '@angular/core';
    
    @Component({
        selector: 'search',
        templateUrl: './result.component.html',
        styleUrls: ['./result.component.scss']
    })
    export class SearchComponent {
    
        public query: string;
    
        @Output() onQuery: EventEmitter<string> = new EventEmitter();
    
        constructor() {}
    
        public handlerEnterSearch() {
            this.onQuery.emit(this.query)
        }
    }


    search.html:

    <div class="input-group input-group-lg p-5">
        <input
            [(ngModel)]="query"
            type="text"
            class="form-control"
            placeholder="Что ищем?"
            (keyup.enter)="handlerEnterSearch()"
        >
        <div class="input-group-append">
            <button class="btn btn-primary" type="button" (click)="handlerEnterSearch()">Найти фильм</button>
        </div>
    </div>


    result.component.ts

    import { Component, OnInit, Input } from '@angular/core';
    import { HttpService } from '../http.service'
    
    @Component({
      selector: 'result',
      templateUrl: './result.component.html',
      styleUrls: ['./result.component.scss']
    })
    export class ResultComponent implements OnInit {
    
      // Вот эти items выводятся в html результата
      @Input()
      items: any[];
    
      constructor(){}
    }


    search-result.html:

    <search (onQuery)="doSearch($event)">
    <result [items]="result">


    search-result.component.ts:

    import { Component, OnInit } from '@angular/core';
    import { HttpService } from '../http.service'
    
    @Component({
        selector: 'search-result',
        templateUrl: './search-result.component.html',
        styleUrls: ['./search-result.component.scss']
    })
    export class SearchResultComponent implements OnInit {
    
        items:any[];
    
        constructor(private httpService: HttpService){
    
        }
    
        // Вот это неудачная часть. Её можно сделать веселее, но для этого необходимо понимать как устроен RxJS.
        // Я не знаю как это объяснить без написания отдельной статьи.
        // На первое время такой подход сойдёт.
        doSearch(query: string) {
            this.httpService.getFilms(query).subscribe((items) => {
              this.items = items;
            })
        }
    }


    Использование сервисов для передачи данных между компонентами в ангуляре - это самые распространённые грабли во фреймворке. Причём эти грабли настолько хитрые, что большинство программистов даже не понимает что ходит по ним. Самый верный способ не наступать на грабли - это забыть навсегда про private и public переменные в сервисах (другими словами сервис не должен иметь состояние). Без этого можно жить и причём легко и спокойно если начать использовать NxRx для хранения состояния системы.
    Ответ написан
    2 комментария
  • Как зарабатывать 1000$ на фрилансе верстальщику?

    HamSter007
    @HamSter007
    HTML/CSS верстальщик
    3 года верстаете на фрилансе и до сих пор не поняли, что верстка бесперспективное направление?! 3 года уже точно как!

    Для развития и большего заработка нужно учить js --> js фреймворки (angular, react, vue, ... ).
    + Чтобы что-то заработать нужно знать английский и выходить на иностранные биржи (на upwork посадка на wp весьма актуальный заказ).
    + Научиться работать по часам, сейчас и отечественные уже переходят на такой формат работы.
    + Если 30 отзывов уже есть, то и сами понимаете что умение предложить свои услуги на приличный проект тоже немаловажный аспект.

    Посмотрите на требования в вакансиях, посмотрите какие заказы более оплачиваемы на фрилансе и поймете что еще нужно подтянуть.
    Ответ написан
    Комментировать
  • Как правильно делать запросы к API в ангуляр 7?

    @sidni
    Php Developer
    В гет запросах параметры надо/можно указывать в параметры урла
    https://api.themoviedb.org/3/movie/search?title=Ма...
    Хотя по коду у вас еще третий параметр вырисовывается query
    А вообще поидеи вам нужно делать сервис по работе с апи чтобы не дублировать код для сбора запроса и исходных данных и этот сервис инжектить в компонент вместо httpclient
    Ответ написан
    1 комментарий
  • Как правильно делать запросы к API в ангуляр 7?

    @msdosx86
    search(title: string): void {
      const params = new HttpParams()
        .set('api_key', 'd6a5ac2d3d7cab11a084ca8080421b20')
        .set('title', title);
      const url = 'https://api.themoviedb.org/3/movie/search';
      this.httpClient.get(url, { params })
        .subscribe(console.log);
    }


    Это ужасный, но понятный для вас пример. Вызовы к API надо выносить в сервисы, метод `subscribe` никогда не вызывайте в методах, только один раз в OnInit, а потом дергать его с помощью `.next`.
    Ответ написан
    6 комментариев
  • Как обновить компонент Vue.js?

    @Artem0071
    Безработный mr. Junior
    Кароч
    На самом деле все проще чем тут пытаются навязать

    Все функции делайте в methods().

    Когда первый раз загружаете компонент, то вместо всей функции вызывайте соответствующий метод, например this.startComponent()

    Затем создаете watch

    Этот watch будет выглядеть как то так:
    watch: {
      '$route'(){
          this.startComponent()
      }
    }


    И тогда все заработает как вы хотите

    Про watch с route можете прочитать тут
    Ответ написан
    2 комментария
  • Как правильно проверять на валидность значение input и правильно выстроить ее архитектуру?

    @karambafe
    Стандартная проблема с кастомными инпутами и валидацией в форме.

    Одно из решений - в форме создать один массив ошибок с поинтерами, указывающими на определенный input. Особенно это хорошо, когда бекенд на этапе проверки формы возвращает ошибки тоже с конкретными поинтерами.

    Пример кастомного инпута c выводом текста ошибки под ним. Если есть хоть одна ошибка, то навешивается "ошибочный" класс со своими стилями.
    <template>
      <div class="input">
        <input
          type="text"
          class="input__field"
          :class="{ 'input__field_error': errors.length > 0 }"
          :placeholder="placeholder"
          :value="value"
          :disabled="disabled"
          @input="handleInput"
        >
    
        <div class="input__errors">
          <p
            v-for="(error, index) in errors"
            :key="index"
            class="input__error"
          >
            {{ error }}
          </p>
        </div>
      </div>
    </template>
    
    <script>
    export default {
      name: 'custom-input',
      props: {
        disabled: {
          type: Boolean,
          default: false,
        },
        errors: {
          type: Array,
          default: () => ([]),
        },
        value: {
          type: String,
          default: '',
        },
        placeholder: {
          type: String,
          default: '',
        },
      },
      methods: {
        handleInput({ target: { value } }) {
          this.$emit('onInput', value);
        },
      },
    };
    </script>


    А в форме уже мы распределяем все ошибки по нужным инпутам:
    <template>
    <form @onSubmit.prevent="handleSubmit">
      <custom-input
         :value="phone"
         :disabled="loading"
         :errors="phoneErrors" // передаем только относящиеся к конкретному инпуту ошибки
         @onInput="handleInput"
      />
    
      <button type="submit">Отправить</button>
    </form>
    </template>
    
    <script>
    export default {
      data: () => ({
         phone: '',
         errors: [],
         loading: false,
      }),
      computed: {
         phoneErrors() {
           // этот код лучше вынести в хелпер, чтобы потом переиспользовать с другими поинтерами
            if (this.errors.length === 0) return [];
            
            return this.errors
             .filter(error => error.pointer === 'phone') // проверка на нужный поинтер
             .map(item => item.detail); // делаем массив только из текста ошибок
         },
      },
      methods: {
        handleInput(newPhone) {
         // при вводе нового значения обнуляем все ошибки. 
         // Можно сделать обнуление ошибок по конкретному поинтеру
          this.errors = []; 
          this.phone = newPhone;
        },
        handleSubmit() {
            this.errors = [];
    
           // Если инпут пустой, то сами генерируем ошибку
           // и не делаем отправку данных на сервер
           if (this.phone.length === 0) {
            this.errors = [...this.errors, {
              detail: 'Телефон не может быть пустым',
              pointer: 'phone',
            }];
            return;
          }
    
          // Если же все ок, то отправляем данные на сервер
          this.loading = true;
          this.sendPhone();
        },
      },
    };
    </script>


    Возможно это и многословный код, но он хорошо читается, понятен и крайне легко покрывается unit тестами
    Ответ написан
    2 комментария