Если оператор и ElementRef для изменения цвета фона не работают [Angular]

Я пытаюсь сделать фон текста зеленым, если напечатан случай 3 и принято ваше предложение. Я хочу использовать elementRef для доступа к DOM и javascript, чтобы добавить цвет фона, используя оператор if. Я добавил оператор if в конце моего файла component.ts, однако он сломал программу, до этого она работала нормально и печатала правильно. На консоли не отображается сообщение об ошибке. Как я могу добиться желаемого поведения, чтобы изменить цвет фона с помощью этого метода? Заранее спасибо. Вот мои файлы .component.ts и .html:

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';

@ViewChild('latestSystemMessage', { static: true })
latestSystemMessage: ElementRef;

export class MessagesComponent implements OnInit {

getLatestSystemMessage(thread: Thread): string {
        const message = thread.messages.slice().reverse().find(m => m.type !== 0);

        const isUserOwner = thread.project.user.id === this.user.id;

        let content = '';

        if (message) {
            switch (message.type) {
                case 1:
                    if (<any>message.content > 0) {
                        content = isUserOwner ?
                            `Offered you $${message.content}` :
                            `You offered $${message.content}`;
                    } else {
                        content = isUserOwner ?
                            `Offered to translate for free` :
                            `You offered to translate for free`;
                    }
                    break;
                case 2:
                    content = isUserOwner ?
                        'Cancelled offer' :
                        'You cancelled your offer';
                    break;
                case 3:
                    content = isUserOwner ?
                        'You accepted the offer' :
                        'Accepted your offer';
                    break;
                case 4:
                    content = isUserOwner ?
                        "You accepted another translator's offer" :
                        "Accepted another translator's offer";
                    break;
            }
        }
        
        if(this.latestSystemMessage.nativeElement === "Accepted your offer" ){
            this.latestSystemMessage.nativeElement.style.backgroundColor="green";
        }else{};

        return content;
    }

Вот мой .html файл

<p class="mb-0" #latestSystemMessage><strong>{{getLatestSystemMessage(thread)}}</strong></p>

person codingkittz    schedule 31.10.2020    source источник
comment
Сделать это можно с помощью привязки в html файле. Есть ли какая-то конкретная причина не использовать этот подход?   -  person Sudipto Mukherjee    schedule 31.10.2020
comment
@SudiptoMukherjee да, это работает ... Мне просто интересно, почему этот метод не работает, поэтому я могу узнать, что я сделал неправильно здесь   -  person codingkittz    schedule 31.10.2020


Ответы (1)


Во-первых, ваш дочерний элемент представления объявлен вне компонента, он должен быть внутри.

Но вы пытаетесь пойти против угловых принципов. Вместо доступа к DOM с помощью дочернего элемента представления определите свойство и оцените это свойство из своей разметки.

Определите класс css/sass в файле стиля вашего компонента для вашего зеленого фона:

.acceptedoffer {
   background: green;
}

Затем в классе typescript вашего компонента определите логическое свойство, указывающее, является ли это принятым предложением:

export class MessagesComponent implements OnInit {
isAcceptedOffer: boolean = false;

Установите это свойство в нужное время в методе getLatestSystemMessage и избавьтесь от viewchild.

Чтобы следовать вашей текущей бизнес-логике, я добавил эту строку в ваш случай 3:

this.isAcceptedOffer = !isUserOwner;

Теперь ваш компонент должен выглядеть так:

import { Component, OnInit } from '@angular/core';

export class MessagesComponent implements OnInit {
isAcceptedOffer: boolean = false;

getLatestSystemMessage(thread: Thread): string {
        const message = thread.messages.slice().reverse().find(m => m.type !== 0);

        const isUserOwner = thread.project.user.id === this.user.id;

        let content = '';

        if (message) {
            switch (message.type) {
                case 1:
                    if (<any>message.content > 0) {
                        content = isUserOwner ?
                            `Offered you $${message.content}` :
                            `You offered $${message.content}`;
                    } else {
                        content = isUserOwner ?
                            `Offered to translate for free` :
                            `You offered to translate for free`;
                    }
                    break;
                case 2:
                    content = isUserOwner ?
                        'Cancelled offer' :
                        'You cancelled your offer';
                    break;
                case 3:
                    this.isAcceptedOffer = !isUserOwner;
                    content = isUserOwner ?
                        'You accepted the offer' :
                        'Accepted your offer';
                    break;
                case 4:
                    content = isUserOwner ?
                        "You accepted another translator's offer" :
                        "Accepted another translator's offer";
                    break;
            }
        }

        return content;
    }

И последнее, но не менее важное: в вашей разметке условно добавьте класс css к значению isAcceptedOffer, равному true, и удалите дочернее объявление представления:

<p class="mb-0" [class.acceptedoffer]="isAcceptedOffer"><strong>{{getLatestSystemMessage(thread)}}</strong></p>

Теперь я понимаю, что вы могли поделиться только частью кода компонента, и это может быть некоторая дополнительная сложность, но все же я думаю, что вам следует попытаться провести рефакторинг и использовать angular так, как он предназначен для использования.

person Yoan Desforges    schedule 31.10.2020
comment
Спасибо, это работает! Знаете ли вы, как называется [class.functionName], который мы используем, чтобы я мог узнать о нем больше, спасибо - person codingkittz; 31.10.2020
comment
angular.io/guide/attribute-binding Это называется привязкой атрибутов. В этом документе есть раздел о классах, но я предлагаю вам потратить время, чтобы прочитать его целиком. - person Yoan Desforges; 31.10.2020
comment
Спасибо, я сделал, это было очень полезно! - person codingkittz; 01.11.2020