Javascript 从另一个对象注册对象的属性更改
在我的项目中,我有一个Javascript 从另一个对象注册对象的属性更改,javascript,typescript,design-patterns,es6-proxy,Javascript,Typescript,Design Patterns,Es6 Proxy,在我的项目中,我有一个widgetBar,它可以包含一个或多个小部件 单击widgetBar中的小部件图标时,会打开一个面板,显示所按下的小部件的内容(类似于带有所有下拉菜单的导航栏) 每个widget都是一个类,它有一个togglePanel()方法,绑定到widget图标上的onlcick事件并打开/关闭面板。此方法还将小部件的isActive属性设置为true(当面板打开时)或false(当面板关闭时) WidgetBar构造函数将widgets的列表作为参数,该参数将成为其this.wi
widgetBar
,它可以包含一个或多个小部件
单击widgetBar中的小部件图标时,会打开一个面板,显示所按下的小部件的内容(类似于带有所有下拉菜单的导航栏)
每个widget
都是一个类,它有一个togglePanel()
方法,绑定到widget图标上的onlcick事件并打开/关闭面板。此方法还将小部件的isActive
属性设置为true
(当面板打开时)或false
(当面板关闭时)
WidgetBar
构造函数将widget
s的列表作为参数,该参数将成为其this.widgets
属性。它还有一个getWidgets()
方法,可以访问此属性
class WidgetBar {
private widgets: Widget[];
constructor(widgets: Widget[]) {
this.widgets = widgets;
}
getWidgets() {
return this.widgets;
}
}
(我的项目)规则是,每当一个小部件打开它的面板时,所有其他面板都应该关闭
如何从WidgetBar
自动检查其小部件
s是否更改了其isActive
属性,以便确保每次打开的面板不超过一个
我读过,但我不确定这是否能帮助我解决这个问题
编辑
那怎么办
将小部件的属性设置为可观察的isActive
类,并从WidgetBar
订阅以侦听任何更新是否是一个好主意,如中所述?您可以在小部件打开时使用它们。小部件栏的工作是执行“规则”。当它获得一个新的open事件时,您可以让它在所有其他子窗口小部件上调用close(通过ViewChild/viewchilds)
或者,您可以将逻辑移出组件,并拥有一个负责所有逻辑的服务。该服务可以通过rxjs订阅将小部件及其属性(如活动)公开到小部件栏。打开小部件时,您可以拥有这些小部件。小部件栏的工作是执行“规则”。当它获得一个新的open事件时,您可以让它在所有其他子窗口小部件上调用close(通过ViewChild/viewchilds)
或者,您可以将逻辑移出组件,并拥有一个负责所有逻辑的服务。该服务可以通过rxjs订阅将小部件及其属性(如活动)公开到小部件栏。这对我来说有点棘手,但最终我解决了我的问题
我所做的是创建一个新属性this.widgetActivated$=newsubject()每次打开小部件面板时,我都会使用类似于{id:currentWidget.id,isActive:currentWidget.isActive}
的对象来填充代码>调用.next()
。然后我订阅它,并在其他处于活动状态且具有不同id的小部件上调用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};
}
}
接口状态{
id:字符串;
isActive:布尔型;
}
WidgetBar类{
私有小部件:小部件[];
私有widgetActivated$:Subject;//重要更改
构造函数(小部件:小部件[]){
this.widgetActivated$=new Subject();//重要更改
this.widgets=widgets;
}
getWidgets(){
返回这个.widgets;
}
私有widgetHandler(小部件:小部件){
fromEvent(widget.widgetBox,'click')。订阅(
()=>this.toggleWidgetPanel(小部件)
);
此.widgetActivated$.subscribe(状态=>{
const widgetsToClose=this.getWidgets().filter(widget=>
widget.isActive==true&&widget.id!==status.id);
如果(widgetsToClose){
forEach(widgetToClose=>this.closePanel(widgetToClose));
}
})
}
私有切换WidgetPanel(小部件:小部件){
如果(!widget.getPanel().classList.contains(“活动”)){
这个.openPanel(小部件);
}否则{
这个.closePanel(小部件);
}
}
私有openPanel(小部件:小部件){
getPanel().classList.add(“活动”);
widget.isActive=true;
this.widgetActivated$.next(this.getWidgetStatus(小部件));//重要更改
}
专用关闭面板(小部件:小部件){
widget.getPanel().classList.remove(“活动”);
}
私有getWidgetStatus(widget:widget):widgetStatus{
返回{id:widget.id,isActive:widget.isActive};
}
}
我还转换了this.element.onclick=this.togglePanel.bind(this)代码>从事件(widget.widgetBox,'click')中订阅(()=>this.toggleWidgetPanel(widget))代码>因为我觉得它更具可读性,并且它没有带来很多关于这个arg
上下文的问题(请参阅)。这对我来说有点棘手,但最后我用它解决了我的问题
我所做的是创建一个新属性this.widgetActivated$=newsubject()每次打开小部件面板时,我都会使用类似于{id:currentWidget.id,isActive:currentWidget.isActive}
的对象来填充代码>调用.next()
。然后我订阅它,并在其他处于活动状态且具有不同id的小部件上调用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};
}
}
接口状态{
id:字符串;
isActive:布尔型;
}
WidgetBar类{
私有小部件:小部件[];
私有widgetActivated$:Subject;//重要更改
构造函数(小部件:小部件[]){
this.widgetActivated$=new Subject();//重要更改
this.widgets=widgets;
}
getWidgets(){
返回这个.widgets;
}
私有widgetHandler(小部件:小部件){
fromEvent(widget.widgetBox,'click')。订阅(
()=>this.toggleWidgetPanel(小部件)
);
此.widgetActivated$.subscribe(状态=>{
const widgetsToClose=this.getWidgets().filter(widget=>