在我的项目中,我有一个widgetBar
,其中可以包含一个或多个widget
。
单击widgetBar中的widget图标时,将打开一个面板,以显示按下的widget的内容(带有所有下拉菜单的导航栏的类型)。
每个widget
是一个具有togglePanel()
方法的类,该方法绑定到小部件图标上的onlcick事件并打开/关闭面板。此方法还将小部件的isActive
属性设置为true
(当面板打开时)或false
(当面板关闭时)。
class Widget {
isActive: boolean = false;
element: HTMLElement;
id: string;
constructor(id: string) {
this.id = id;
this.element = document.crateElement('DIV');
// ... this.element and other things represent the widget DOM object
this.element.onclick = this.togglePanel.bind(this);
}
togglePanel() {
if (this.panel.classList.contains('active')) {
this.openPanel();
this.isActive = true;
} else {
this.closePanel();
this.isActive = false;
}
}
}
WidgetBar
构造函数将widget
的列表作为参数,成为其this.widgets
属性。它还具有getWidgets()
方法,可以访问此属性。
class WidgetBar {
private widgets: Widget[];
constructor(widgets: Widget[]) {
this.widgets = widgets;
}
getWidgets() {
return this.widgets;
}
}
(我的项目的)规则是,每当一个小部件打开其面板时,所有其他面板都应关闭。
如何自动从WidgetBar
中检查其widget
之一是否更改了其isActive
属性,以便确保一次只能打开一个面板? ?
我了解了Proxy
,但是我不确定这是否可以帮助我解决此问题。
将isActive
类的Widget
属性设置为Observable,并从WidgetBar
订阅以侦听任何更新是一个好主意,如this answer中所述?
答案 0 :(得分:0)
打开小部件emit an event时,您可以使用它们。小部件栏的工作是强制执行“规则”。当它收到新的打开事件时,您可以让它在所有其他子窗口小部件上调用关闭(通过ViewChild / ViewChildren)。
或者,您可以将逻辑移出组件,并拥有负责所有逻辑的服务。该服务可以通过可订阅的rxjs向窗口小部件栏显示窗口小部件及其属性(例如,活动的)。
答案 1 :(得分:0)
这对我来说有点棘手,但最终我用rxjs Subjects
解决了我的问题。
我要做的是创建一个新属性not equal
2.9999999999999999e+100
3.0000000000000006e+100
,每当打开小部件面板时,我都会使用诸如this.widgetActivated$ = new Subject();
之类的对象来填充.next()
。然后,我订阅它,并在其他处于活动状态且具有不同ID的小部件上调用{id: currentWidget.id, isActive: currentWidget.isActive}
。
这是更新的代码:
closePanel()
我也将interface widgetStatus {
id: string;
isActive: boolean;
}
class WidgetBar {
private widgets: Widget[];
private widgetActivated$: Subject<widgetStatus>; // IMPORTANT CHANGE
constructor(widgets: Widget[]) {
this.widgetActivated$ = new Subject(); // IMPORTANT CHANGE
this.widgets = widgets;
}
getWidgets() {
return this.widgets;
}
private widgetHandler(widget: Widget) {
fromEvent(widget.widgetBox, 'click').subscribe(
() => this.toggleWidgetPanel(widget)
);
this.widgetActivated$.subscribe(status => {
const widgetsToClose = this.getWidgets().filter(widget =>
widget.isActive === true && widget.id !== status.id);
if (widgetsToClose) {
widgetsToClose.forEach(widgetToClose => this.closePanel(widgetToClose));
}
})
}
private toggleWidgetPanel(widget: Widget) {
if (!widget.getPanel().classList.contains("active")) {
this.openPanel(widget);
} else {
this.closePanel(widget);
}
}
private openPanel(widget: Widget) {
widget.getPanel().classList.add("active");
widget.isActive = true;
this.widgetActivated$.next(this.getWidgetStatus(widget)); // IMPORTANT CHANGE
}
private closePanel(widget: Widget) {
widget.getPanel().classList.remove("active");
}
private getWidgetStatus(widget: Widget): widgetStatus {
return {id: widget.id, isActive: widget.isActive};
}
}
转换为this.element.onclick = this.togglePanel.bind(this);
,因为我觉得它更具可读性,并且没有带来关于fromEvent(widget.widgetBox, 'click').subscribe(() => this.toggleWidgetPanel(widget));
上下文的很多问题(请参阅this other question of mine)。