业务组件A依赖于业务服务,其中包含:
true:所有可折叠组件默认情况下都处于打开状态。
false:默认情况下应关闭所有可折叠组件。
A通过绑定到多个技术子组件B的单向属性来传递此知识(计算,而不是存储的值),这些子组件定义了可折叠组件的模板(它们的内容是特定业务组件的投影)。
当第一次渲染A和B时,绑定被解析,并且B接受以下知识:可折叠的组件知道它们应该显示其内容还是将其隐藏。尽管如此,如果用户愿意,他们仍然提供一个按钮来显示或隐藏内容。
注意:可折叠组件不会注入服务本身来直接访问知识,因为它是业务服务,并且是技术组件。
在A中执行操作后,我想“重新解析”与[[B绑定的属性,所以我希望A再次将服务知识传递给B并因此覆盖用户的任何操作(例如:如果他打开了默认情况下处于关闭状态的可折叠组件,我希望将其恢复为默认状态(即已关闭))。
最简单的解决方案是重新渲染组件(销毁/创建),但我不想这样做,因为:[1)我不希望用户看到由组件的破坏/渲染引起的闪烁。
[2)
除了这个问题,没有充分的理由重新渲染组件。代码@Component({
selector: 'business-parent',
template: '
<generic-collapsable-component [opened]="businessHelper.conditionA">
// A business-child component
</generic-collapsable-component>
// More generic-collapsable-component
'
})
export class BusinessParentComponent {
constructor(private businessHelper: BusinessHelper) {
}
onBusinessAction() {
// Here I do some business stuff...
// And I want to force the binding [opened] to re-execute its default value, so I want GenericCollapsableComponent.opened = businessHelper.conditionA, and not what I currently have, which is the value of the last GenericCollapsableComponent.switch() I called.
}
}
@Component({
selector: 'generic-collapsable-component',
template: '
<button (click)="switch()">Switch to show or hide content</button>
<div [ngClass]="{'is-hidden': !isOpen()}"
<ng-content></ng-content>
</div>
'
})
export class GenericCollapsableComponent {
@Input() opened: boolean; // Is intialized by the parent component but can be modified by the inner switch() method called in the template.
constructor() {
}
switch(): void {
this.opened = !this.opened;
}
isOpen(): boolean {
return this.opened;
};
}
解决方案
可折叠组件:
export class GenericCollapsableComponent {
@Input() opened: boolean;
@Output() openedChange = new EventEmittter<boolean>(); //must have the variable name followed by "Change"
constructor() {
}
switch(): void {
this.opened = !this.opened;
this.openedChange.emit(this.opened); //alert the parent that the "opened" state has changed
}
isOpen(): boolean {
return this.opened;
};
}
折叠组件的用法:<generic-collapsible [(opened)]="isOpened">
<div>Some content!</div>
</generic-collapsible>
以及背后的代码:export class ParentComponent {
isOpened: boolean = true;
}
然后在父组件中,您可以