Классы ES6 — выбор цепочки

#javascript #ecmascript-6 #callback

#javascript #ecmascript-6 #обратный вызов

Вопрос:

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

Вот что я пытаюсь сделать:

  • первый уровень будет отображаться при загрузке
  • при изменении уровня будет загружаться его подуровень
  • в группе должны быть все загруженные уровни
  • должно быть бесконечное количество уровней

введите описание изображения здесь

Вот что сделано до сих пор:

 class TierGroup {

  constructor() {
        this.$tiersContainer = $('#tiers');
        this.group =[];
        this.createTier();

  }

  createTier() {

        let tier = new Tier();
        tier.$select.on('change', e => {

            let tier =new Tier();

            tier.$select.on('change', e => {
                    let tier =new Tier();
                    this.group.push(tier);
                    this.$tiersContainer.append(tier.$select);

            });

            this.group.push(tier);
            this.$tiersContainer.append(tier.$select);

        });

        this.$tiersContainer.append(tier.$select);
        this.group.push(tier);

  }  

}

class Tier {
  constructor() {
    this.$select =$('<select/>');
    this.load();
  }

  load() {
    axios.get('https://jsonplaceholder.typicode.com/users').then(res => {
      for (let row in res.data) {
        this.$select.append('<option>' res.data[row].name '</option>')
      }
    })
  }

}


var tier =new TierGroup();
  

https://jsbin.com/buziyu/edit?html ,js, вывод

Спасибо за ваше время!

Ответ №1:

Я не уверен, что у меня проблема … если это «Я хотел бы иметь бесконечную цепочку без бесконечной вложенности вручную», это мое решение.

Применение принципа единой ответственности является ключом к решению этой проблемы на самом деле 🙂

Как вы можете видеть в своем коде, createTier метод выполняет четыре действия (что слишком много):

  • создает новый уровень;
  • прикрепляет к нему обработчик (с его собственным определением, слишком много);
  • добавьте совершенно новый уровень к группе и dom;
  • координируйте эти шаги.

Я бы извлек из этого метода два отдельных для:

  1. создание уровня с его обработчиком;
  2. добавление уровня.

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

 buildTier() {
  let tier = new Tier();
  tier.$select.on('change', /* something here */)
  return tier
}
  

Вместо этого добавление уровня может быть чем-то вроде:

 appendTier(tier) {
  this.$tiersContainer.append(tier.$select);
  this.group.push(tier);
}
  

Теперь давайте оставим работу по координации этого материала создателю, это стало бы:

 createTier() {
  const newTier = this.buildTier()
  this.appendTier(newTier)
}
  

или даже:

 createTier() {
  this.appendTier(this.buildTier())
}
  

Как вы можете видеть, каждый метод выполняет только одну вещь. Интересная часть заключается в том, что нигде уровень не связан с его потомком или родительским, что означает, что мы можем использовать createTier в качестве обработчика для выбора, уделяя внимание передаче текущего контекста:

 buildTier() {
  let tier = new Tier();
  tier.$select.on('change', this.createTier.bind(this))
  return tier
}
  

Надеюсь, это поможет 🙂

https://jsbin.com/wuviqoxohu/edit?html ,js, вывод

Комментарии:

1. Извините за мое запутанное описание. Ваше решение — это именно то, что мне было нужно, потрясающе! спасибо, что уделили время! Я был довольно близок к этому, но мой мозг просто застрял на обратном вызове для события выбора, мне не хватало этой привязки. Мне очень любопытно, как / откуда вы узнали о такого рода вещах, потому что я много искал это решение без какого-либо ответа. Вы рекомендуете какие-нибудь книги, руководства? еще раз спасибо! хорошего дня

2. Рад помочь :). Я бы предположил, что вы не знаете серию книг по JS и курс Deep Javascript Foundations для мастеров интерфейса, оба от getify 😉