Я пытаюсь построить простую ролевую игру, используя Angular. У меня есть консольный журнал, отображающий такие события, как Damage Dealt / Experience заработал.
У меня есть вызов службы MessageService, где у меня есть свойство массива типа Message (текст, дата, тип).
import { Message } from "@core/models/message";
import { Injectable } from "@angular/core";
import { MESSAGE } from "@core/constant/constant";
@Injectable({
providedIn: "root"
})
export class MessageService {
messages: Message[] = [];
private add(message: String, type: string) {
this.messages.push(new Message(message, type));
}
addGeneralMessage(message: String) {
this.add(message, MESSAGE.GENERAL);
}
addCombatMessage(message: String) {
this.add(message, MESSAGE.COMBAT);
}
clear() {
this.messages = [];
}
constructor() {}
}
У меня есть кнопки в журнале консоли, позволяющие пользователю «фильтровать» все сообщения, чтобы получить только указанный тип c (Бой / Общий / Система).
Я могу фильтровать, используя: messages.filter (message => message.type == type), что я не могу сделать, так это продолжать получать новое сообщение выбранного типа.
import { Message } from "@core/models";
import { MESSAGE } from "@core/constant/constant";
import { MessageService } from "@core/services";
import { Component, OnInit } from "@angular/core";
@Component({
selector: "app-message",
templateUrl: "./message.component.html",
styleUrls: ["./message.component.scss"]
})
export class MessageComponent implements OnInit {
messages: Message[];
constructor(public messageService: MessageService) {}
ngOnInit() {
this.messages = this.messageService.messages;
}
filterByType(type: String) {
if (type == MESSAGE.ALL) {
this.messages = this.messageService.messages;
} else {
this.messages = this.messageService.messages.filter(
item => item.type == type
);
}
}
}
Есть идеи? Я попытался использовать observable, но безуспешно. Думаю, у меня не получилось хорошо его реализовать.
РЕДАКТИРОВАТЬ: Мой компонент сообщения выглядит следующим образом:
<div class="log">
<app-message-button-menu
(filter)="filterByType($event)"
></app-message-button-menu>
<app-message-chat [messages]="messages"></app-message-chat>
</div>
мой app-message-button-menu вроде что:
<div class="menuLog">
<app-message-button
[text]="'All'"
[type]="MESSAGE.ALL"
[active]="activeButton == MESSAGE.ALL"
(messageType)="onFilter($event)"
></app-message-button>
<app-message-button
[text]="'General'"
[type]="MESSAGE.GENERAL"
[active]="activeButton == MESSAGE.GENERAL"
(messageType)="onFilter($event)"
></app-message-button>
<app-message-button
[text]="'Fight'"
[type]="MESSAGE.COMBAT"
[active]="activeButton == MESSAGE.COMBAT"
(messageType)="onFilter($event)"
></app-message-button>
<app-message-button
[text]="'System'"
[type]="MESSAGE.SYSTEM"
[active]="activeButton == MESSAGE.SYSTEM"
(messageType)="onFilter($event)"
></app-message-button>
</div>
import { Component, OnInit, Output, EventEmitter, Input } from "@angular/core";
@Component({
selector: "app-message-button",
templateUrl: "./message-button.component.html",
styleUrls: ["./message-button.component.scss"]
})
export class MessageButtonComponent implements OnInit {
@Input() type: String;
@Input() text: String;
@Input() active: boolean;
@Output() messageType = new EventEmitter<String>();
constructor() {}
ngOnInit() {}
filter() {
this.messageType.emit(this.type);
}
}
import { Component, OnInit, Output, EventEmitter, Input } from "@angular/core";
@Component({
selector: "app-message-button",
templateUrl: "./message-button.component.html",
styleUrls: ["./message-button.component.scss"]
})
export class MessageButtonComponent implements OnInit {
@Input() type: String;
@Input() text: String;
@Input() active: boolean;
@Output() messageType = new EventEmitter<String>();
constructor() {}
ngOnInit() {}
filter() {
this.messageType.emit(this.type);
}
}
моя кнопка-сообщение-приложение вот так:
<button [ngClass]="{ active: active == true }" (click)="filter()" type="button">
{{ text }}
</button>
import { Component, OnInit, Output, EventEmitter, Input } from "@angular/core";
import { MESSAGE } from "@core/constant/constant";
@Component({
selector: "app-message-button-menu",
templateUrl: "./message-button-menu.component.html",
styleUrls: ["./message-button-menu.component.scss"]
})
export class MessageButtonMenuComponent implements OnInit {
MESSAGE;
activeButton: String;
@Output() filter = new EventEmitter<String>();
constructor() {}
ngOnInit(): void {
this.MESSAGE = MESSAGE;
this.activeButton = MESSAGE.ALL;
}
onFilter(type: String) {
this.activeButton = type;
this.filter.emit(type);
}
}
и вот мой-чат-приложение:
<ul>
<app-message-item
*ngFor="let message of messages; trackBy: trackBy"
[message]="message"
></app-message-item>
</ul>
import { Component, OnInit, Input } from "@angular/core";
import { Message } from "@core/models/message";
@Component({
selector: "app-message-chat",
templateUrl: "./message-chat.component.html",
styleUrls: ["./message-chat.component.scss"]
})
export class MessageChatComponent implements OnInit {
@Input("messages") messages: Message[];
constructor() {}
ngOnInit(): void {}
trackBy(index: number, item: Message): Message {
return item;
}
}
РЕДАКТИРОВАТЬ Линг Vu Ответ работы:
import { Message } from "@core/models/message";
import { Injectable } from "@angular/core";
import { MESSAGE } from "@core/constant/constant";
import { ReplaySubject } from "rxjs";
@Injectable({
providedIn: "root"
})
export class MessageService {
messages: Message[] = [];
filteredMessages: ReplaySubject<Message[]> = new ReplaySubject(1);
filter: String;
private add(message: String, type: string) {
this.messages.push(new Message(message, type));
this.filterMessages();
}
addGeneralMessage(message: String) {
this.add(message, MESSAGE.GENERAL);
}
addCombatMessage(message: String) {
this.add(message, MESSAGE.COMBAT);
}
clear() {
this.messages = [];
}
setFilter(filter: String) {
this.filter = filter;
}
filterMessages() {
if (!this.filteredMessages)
this.filteredMessages = new ReplaySubject(1);
if (this.filter === MESSAGE.ALL) {
this.filteredMessages.next(this.messages);
} else {
this.filteredMessages.next(
this.messages.filter(item => item.type === this.filter)
);
}
}
constructor() {}
}
мой компонент сообщения:
export class MessageComponent implements OnInit {
messages: Message[];
constructor(public messageService: MessageService) {}
ngOnInit() {
this.messageService.setFilter(MESSAGE.ALL);
this.messageService.filteredMessages.subscribe(
messages => (this.messages = messages)
);
}
filterByType(type: String) {
this.messageService.setFilter(type);
if (type === MESSAGE.ALL) {
this.messages = this.messageService.messages;
} else {
this.messages = this.messageService.messages.filter(
messages => messages.type === type
);
}
}
}
к сожалению, я не нашел, как реализовать свойство Observable в моем компоненте, как он сказал мне. Я найду несколько уроков
Спасибо, Лин Ву