Представление не обновляется немедленно из службы с помощью element.classList.add () - PullRequest
0 голосов
/ 06 февраля 2020

Я добавляю класс css к элементам из службы, но изменения не происходят немедленно. Изменения занимают около секунды, чтобы обновить представление. Мне нужно, чтобы изменения произошли немедленно, без задержек. Я пробовал ApplicaionRef и вызывал this.applicationRef.tick() в службе, но это не сработало. Я попытался запустить метод сервиса в this.zone.run в NgZone, но это также не сработало.

@Component({
  selector: 'calling',
  templateUrl: './calling.component.html',
  styleUrls: ['./calling.component.scss']
})
export class CallingComponent {
 constructor(private hidingService: HidingService) {}

 callHide() {
  this.hidingService.hide();
 }
}
@Injectable({
  providedIn: 'root'
})
export class HidingService {
 constructor() {}

 hide() {
  const elements = document.querySelectorAll('.hideable-field');
  elements.forEach(element => {
    element.classList.add('hide');
  });
 }
}

Вот CSS в стилях. css (доступно из всех компонентов) для ссылка, но эта часть работает. Добавление этого класса 'hide' скрывает поле с этим CSS:

.hideable-field {
  &.hide {
    visibility: hidden !important;
  }
}

Если я использую этот скрытый логик c в Компоненте, он работает. Поля скрыты сразу. Если я использую эту скрытую логику c в сервисе, это займет некоторое время.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2020

Решение оказалось ожидающим обновления пользовательского интерфейса, прежде чем вернуться. Есть метод requestAnimationFrame (), который позволяет вам сделать это.

export class HidingService {
 constructor() {}

 hide(): Observable<{}> {
  const elements = document.querySelectorAll('.hideable-field');
  elements.forEach(element => {
    element.classList.add('hide');
  });

  const subject = new Subject();
  requestAnimationFrame( () => {
    // Fields will hide in this frame
    requestAnimationFrame( () => {
      // Fields are hidden
      subject.next(); 
    });
  });
  return subject.pipe();
 }
}
0 голосов
/ 06 февраля 2020

Обычно это анти-паттерн, когда служба вносит изменения, которые напрямую влияют на HTML вашего компонента. Также не рекомендуется использовать селекторы запросов документов в Angular. НО, если вы хотите, чтобы что-то работало быстро, попробуйте обернуть тайм-аут вокруг функции hide в вашем сервисе:

 hide() {
  setTimeout(() => {
    const elements = document.querySelectorAll('.hideable-field');
    elements.forEach(element => {
      element.classList.add('hide');
    });
  }, 0)
 }

Более правильным подходом было бы иметь логическое свойство isHidden для каждого ваших объектов. Затем из вашего шаблона вы можете использовать [hidden] или *ngIf для их условного отображения. См. Angular2: условное отображение, привязка к свойству [hidden] против директивы * ngIf для описания различия между этими двумя подходами. Пример использования *ngIf:

Где-то в шаблоне вашего компонента:

<ng-container *ngFor='let element of myElements'>
  <div class='my-element' *ngIf='!element.isHidden'></div>
</ng-container>

Новая функция скрытия в вашем компоненте :

 hide() {
   this.myElements.forEach(element => element.isHidden = true);
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...