我有一个文本区域列表:
text-area.component.html
<!--suppress HtmlFormInputWithoutLabel -->
<textarea [ngClass]="generateTextAreaClass()" (keypress)="onKeyPress($event)">{{ value }}</textarea>
文本区域有一个keypress
事件。
当我在一个文本区域中按一个键时,它将触发此组件所有实例的keypress
事件。
结果,我触发了5个事件。显然,这并不代表我作为用户所做的操作。
{textareaSelector: ".app-utility-textarea-1-1", keypressType: "shift+enter"}
{textareaSelector: ".app-utility-textarea-1-1", keypressType: "shift+enter"}
{textareaSelector: ".app-utility-textarea-1-1", keypressType: "shift+enter"}
{textareaSelector: ".app-utility-textarea-1-1", keypressType: "shift+enter"}
{textareaSelector: ".app-utility-textarea-1-1", keypressType: "shift+enter"}
如何限制仅针对当前输入的文本区域触发事件,以便仅触发一个事件?
@Component({
selector: 'app-utility-textarea',
templateUrl: './text-area.component.html',
styleUrls: ['./text-area.component.scss']
})
export class TextAreaComponent implements AfterViewInit {
constructor(private eventBus: EventBusService) {
}
@Input() value: string;
@Input() id: string;
public textAreaClassPrefix = 'app-utility-textarea';
...
generateTextAreaClass(): string {
return `${this.textAreaClassPrefix}-${this.id}`;
}
onKeyPress(event: KeyboardEvent) {
event.stopPropagation();
if (event.key === 'Enter' && event.shiftKey) {
event.preventDefault();
const textAreaKeyPressEvent: TextAreaKeyPressEvent = {
textareaSelector: this.generateTextAreaClassCSSSelector(),
keypressType: TextAreaKeyPressType.SHIFT_ENTER
};
this.eventBus.textAreaKeyPressSubject$.next(textAreaKeyPressEvent);
}
}
}
event-bus.service.ts
@Injectable()
export class EventBusService {
public navbarSubject$ = new BehaviorSubject(DashboardNavbarEvent.SIDEBAR_MENU_CLOSED);
public textAreaKeyPressSubject$ = new Subject<TextAreaKeyPressEvent>();
constructor() {
}
}
subscriber.component.ts
@Component({
selector: 'app-subscriber',
templateUrl: './subscriber.component.html',
styleUrls: ['./subscriber.component.scss']
})
export class SubscriberComponent implements OnInit {
@Input() public block: any;
@Input() public index: number;
constructor(private eventBus: EventBusService) {
}
ngOnInit() {
this.eventBus.textAreaKeyPressSubject$.subscribe((event: TextAreaKeyPressEvent) => {
console.log(event);
});
}
}
答案 0 :(得分:0)
结果证明这是一个设计问题。我正在预订另一个有5个实例的组件中的textAreaKeyPressSubject$
。每个实例最终都在init上订阅了textAreaKeyPressSubject$
,并分别记录了该事件1次。
keypress
事件仅在我输入的textarea.component.ts
中触发一次。
当我将对此主题的订阅移动到只有一个实例的父组件时,此问题已解决。
答案 1 :(得分:0)
您正在使用subject中的主题:
什么是主题? RxJS主题是一种特殊的Observable类型,它允许将值多播到许多Observer。普通的Observable是单播的(每个订阅的Observer拥有Observable的独立执行),而Subject是多播的。
然后您将在下一个发出事件:
this.eventBus.textAreaKeyPressSubject$.next(textAreaKeyPressEvent);
因此,基本上,您正在向多播订户发送一些内容,因此,可以从正确的一个文本区域触发该事件,如您所见,但您正在将该事件传播给其他订户。关键是您想要一对一的订阅而不是一对多的订阅。希望这会有所帮助