При вставке элемента DOM из JavaScript стили CSS не отображаются

#javascript #html #css #angular #dom

#javascript #HTML #css #угловой #dom

Вопрос:

Я хочу отобразить журнал с заголовком и содержимым.

С помощью следующего кода li элементы вставляются в DOM с правом className , но стили не отображаются.

Это находится внутри углового компонента, который, я думаю, может быть причиной ошибки. Это просто базовое новое приложение с HTML: <app-example></app-example>

Примечание: если я вставляю элемент вручную в html, он отображается правильно. Единственное отличие, которое я замечаю , заключается в том , что li элементы , вставленные из javascript , не имеют _ngcontent-cxr-c40 .

HTML:

 <ul class="d-flex f-column log-list" id="log-list">
        <li id="log-item" class="log-message">
          <span class="log-message-title">TEST</span>
        </li>
</ul>
 

Это функция для добавления элемента в журнал:

   private addLogElement(title: string, message: string): void {
    const newNode = document.createElement('li');
    newNode.className = 'log-message';
    const newNodeTitle = document.createElement('span');
    newNodeTitle.className = 'log-message-title';

    const headerText = document.createTextNode(title);

    newNodeTitle.appendChild(headerText);
    newNode.appendChild(newNodeTitle);

    const parentDiv = document.getElementById('log-list');
    const childDiv = document.getElementById('log-item');
    parentDiv.insertBefore(newNode, childDiv);
  }
 

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

1. Ваш код должен работать, но это не «угловой способ». Используйте массив и *ngFor для этого array: angular.io/guide/structural-directives , вам нужно только добавить элемент в массив

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

3. Вероятно, есть некоторая польза от использования renderer2 при работе с dom, но он должен работать только с JS. Проверьте digitalocean.com/community/tutorials/angular-using-renderer2 для получения дополнительной информации

Ответ №1:

Вы должны использовать Renderer2 API для таких манипуляций с DOM.

В классе компонента в конструкторе введите его следующим образом :-

 constructor(public renderer: Renderer2) {}
 

Затем измените свой метод на :-

 private addLogElement(title: string, message: string): void {
    const newNode = this.renderer.createElement('li');
    this.renderer.addClass(newNode, 'log-message');
    const newNodeTitle = this.renderer.createElement('span');
    this.renderer.addClass(newNodeTitle, 'log-message-title');
    const headerText = this.renderer.createText(title);
    this.renderer.appendChild(newNodeTitle, headerText);
    this.renderer.appendChild(newNode, newNodeTitle);

    const parentDiv = this.renderer.selectRootElement(document.getElementById('log-list'), true);
    const childDiv = this.renderer.selectRootElement(document.getElementById('log-item'), true);
    this.renderer.insertBefore(parentDiv, newNode, childDiv);
  }
 

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

Вы можете сослаться на эти причины здесь:- https://medium.com/dev-genius/dont-use-native-dom-manipulations-in-angular-6c8db13f463f

Ответ №2:

Добавьте это в свой css/scss
Я добавил примеры стилей

 :host ::ng-deep .log-message{
    color: red;
}
:host ::ng-deep .log-message-title{
    background-color: #eeee33
}