Как стать автором
Обновить

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

Лисинер, тулитип, опрции…
Проверьте текст на ошибки/опечатки
Здравствуйте. Спасибо за статью.
Как мне кажется — вы подошли к решению задачи не с той стороны. Внутри функции «buildTooltip» вы вычисляете размеры будущего окошка на основе размеров строки и количества переданных «list». И всё ради того что бы проставить элементу нужные размеры и позицию. Почти всё это можно сделать средствами только лишь css. Например вот набросок html+css
<div class="ceil">
  <div class="icon"></div>
  <div class="tooltip">
    <div class="emploee"></div>
    <div class="emploee"></div>
    <div class="emploee"></div>
  </div>
</div>

<style>
  .ceil {
    position: relative;  
  }
  .icon:hover + .tooltip {
    display: flex;
  }
  .tooltip {
    display: none;
    position: absolute;
    flex-wrap: wrap;
    bottom: 0;
    left: 100%;
    max-width: 320px;
  }
  .emploee {
    width: 160px;
  }
</style>


Ни написав ни строчки кода на js мы получили заветный тултип. Вот его отличия от вашей реализации в плане функциональности:
1. Он всегда справа
2. Его ширина не зависит от оставшейся справа длины строки
3. Высота emploee не зависит от высоты строки
4. Его разметка всегда на странице, просто скрыта за display: none.
5. Не реализован показ по клику
6. Окно находится рядом с иконкой, а не в конце body

Если же что-то из этих отличий критично — то всё-таки пишем js код:
1. Не нужно думать за браузера. Намного проще положить элемент на страницу и взять его width\height, чем считать эти свойства самому. Соответственно что бы решить проблему 1 — на событие mouseover берём ширину этого элемента и смотрим — не выходит ли он за границу дозволенного(в вашем случае вы считаете width\height сами — и это самый сложный участок кода). Если выходит — меняем css свойство «left: 100%» на «right: 100%».
2. Тоже самое — с помощью width\height элемента просто превращаем max-width в width на mouseover
3. Тоже 1 строчка в mouseover на height для .emploee
4. Эта проблема решается просто — создаём динамически тултип(как это сделано у вас в showTooltip), только бахаем его не в конец body, а сразу за элементом: this.viewContainerRef.createComponent(TooltipComponent).
5. Просто добавить класс для отмены :hover и добавлять\убирать ещё один при клике для показа
6. Здесь уже посложнее, но подход тот же. Сначала добавляем элемент в конец body -> берём его width\height -> проставляем left\top

Как правило когда я выполняю подобного рода задачки первое что нужно узнать — а нужно ли вообще писать код? Вполне возможно что эти ограничения вполне устроят заказчика — например если справа всегда будет 320px, ширина не доходит до правого края(и это ок), высота строки всегда одинаковая, ну и так далее. По моему опыту часто удаётся упростить код в разы путём незначительных модификаций в требования к функционалу.

Ещё бросается в глаза пара моментов по коду:

1. Если вы используете any в typescript — то скорее всего вы что то делаете не так. Во всех any в вашем коде тип переменной вполне определён.
2. В этом месте:
@Input() showOnClick: boolean = false; 
не обязательно указывать boolean. Если вы устанавливаете false\true при создании — typescript сам поймёт какой это тип(просто лишний код)
3. Если вам при использовании angular приходится работать напрямую с элементами на странице — скорее всего вы что-то делаете не так. Вместо поиска родителя по классу — можно просто заинжектить родительский компонент и уже у него брать необходимые свойства. Вместо этого:
this._document.querySelector('body').appendChild(this.contentCmpRef.location.nativeElement); 
В angular тоже есть более высокоуровневая абстракция — viewContainerRef.createComponent.
Вместо прямого изменения списка классов есть ngClass, и так далее
4. В функции buildTooltip вы получаете переменную «matRow» но ниже её не используете — странно :)

Надеюсь идею уловили :)
Да, исправила ошибки/ опечатки.

Нужен был тултип именно такого вида, а в Материал этого нет.

Длина тултипа должна быть плавающей, это обязательное условие, потому что похожих таблиц не одна а много, и расстояние до конца экрана всегда величина переменная.
Его надо показать чуть сбоку от элемента, чтобы было видно количество человек.

В функции buildTooltip вы получаете переменную «matRow» но ниже её не используете — странно :)

По ней проходит проверка, а нужные данные записываются в переменную родителя сразу.

По поводу скрытия тултипа идея хорошая, я подумаю над ее реализацией! Спасибо за советы!
Почему тултип не построен поверх angular/cdk?
Не понимаю сути вопроса
Для начала неплохо бы исправить слово «коммандировка» в самом приложении, а то глаза режет…
это тестовые данные, спасибо что заметили!
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории