Created
April 9, 2020 23:59
-
-
Save nirkaufman/5a3d450046bb16a17b41ff275e6dc0e4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
ChangeDetectorRef, | |
Component, | |
ComponentFactory, | |
ComponentFactoryResolver, | |
ElementRef, | |
Injector, | |
OnInit, | |
Renderer2, | |
ViewChild, | |
ViewContainerRef | |
} from '@angular/core'; | |
import {WidgetComponent} from "./widget.component"; | |
@Component({ | |
selector: 'nk-layout', | |
template: ` | |
<div class="row"> | |
<div class="col left-area"> | |
<h4>Rate Area</h4> | |
<ng-container #leftSide></ng-container> | |
</div> | |
<div class="col"> | |
<h4>Create & Edit Area</h4> | |
<div class="form-group"> | |
<input class="form-control" | |
#inputRef | |
placeholder="Widget Title" | |
[(ngModel)]="widgetTitle" | |
(keydown.enter)="stopEdit()" | |
name="title"> | |
</div> | |
<button (click)="createWidget()" class="btn btn-primary mr-1">Create</button> | |
<button (click)="removeAll()" class="btn btn-danger">remove all</button> | |
<ng-container #rightSide></ng-container> | |
</div> | |
</div> | |
`, | |
styles: ['.edit {border-color: red}'] | |
}) | |
export class LayoutComponent implements OnInit { | |
@ViewChild('rightSide', {read: ViewContainerRef}) rightSide: ViewContainerRef; | |
@ViewChild('leftSide', {read: ViewContainerRef}) leftSide: ViewContainerRef; | |
@ViewChild('inputRef') inputRef: ElementRef; | |
private widgetFactory: ComponentFactory<WidgetComponent>; | |
private _titleValue: string; | |
selectedWidget: WidgetComponent; | |
constructor( | |
private componentFactoryResolver: ComponentFactoryResolver, | |
private renderer: Renderer2, | |
private changeDetectorRef: ChangeDetectorRef, | |
private injector: Injector) { | |
} | |
// factory should be created only once | |
ngOnInit(): void { | |
this.widgetFactory = this.componentFactoryResolver.resolveComponentFactory(WidgetComponent); | |
this.resetLayoutState(); | |
} | |
set widgetTitle(newTitle: string) { | |
this._titleValue = newTitle; | |
if (this.selectedWidget) { | |
this.selectedWidget.title = this._titleValue; | |
} | |
} | |
get widgetTitle() { | |
return this._titleValue; | |
} | |
// create a widget and insert it to the right side | |
createWidget() { | |
const widgetComponent = this.widgetFactory.create(this.injector) | |
const widgetViewRef = this.rightSide.insert(widgetComponent.hostView); | |
// pass the widget data | |
widgetComponent.instance.title = this.widgetTitle; | |
widgetComponent.instance.viewRef = widgetViewRef; | |
widgetComponent.instance.switch = this.switch.bind(this); | |
widgetComponent.instance.edit = this.edit.bind(this); | |
// reset widget data | |
this.resetLayoutState(); | |
} | |
// detach from one view container and attach to another | |
switch(widget: WidgetComponent) { | |
const widgetViewRef = widget.viewRef; | |
if (this.rightSide.indexOf(widgetViewRef) >= 0) { | |
widget.viewRef = this.leftSide.insert(this.rightSide.detach(this.rightSide.indexOf(widgetViewRef))); | |
this.resetLayoutState(); | |
} | |
if (this.leftSide.indexOf(widgetViewRef) >= 0) { | |
widget.viewRef = this.rightSide.insert(this.leftSide.detach(this.leftSide.indexOf(widgetViewRef))); | |
this.selectedWidget = widget; | |
this.widgetTitle = widget.title; | |
} | |
} | |
edit(widget: WidgetComponent) { | |
// prevent editing when on the left side | |
if (this.leftSide.indexOf(widget.viewRef) < 0) { | |
this.selectedWidget = widget; | |
this.widgetTitle = this.selectedWidget.title; | |
this.renderer.addClass(this.inputRef.nativeElement, 'edit',); | |
} | |
} | |
stopEdit() { | |
this.resetLayoutState(); | |
this.renderer.removeClass(this.inputRef.nativeElement, 'edit'); | |
} | |
removeAll() { | |
this.rightSide.clear(); | |
this.leftSide.clear(); | |
} | |
private resetLayoutState() { | |
this.selectedWidget = null; | |
this.widgetTitle = ''; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Component, Input, OnInit, ViewRef} from '@angular/core'; | |
@Component({ | |
selector: 'nk-widget', | |
template: ` | |
<div class="card my-3"> | |
<div class="card-body"> | |
<h5 class="card-title">{{title}} {{count}}</h5> | |
<button (click)="increase()" class="btn btn-sm btn-success mr-1">UP</button> | |
<button (click)="decrement()" class="btn btn-sm btn-info mr-1">DOWN</button> | |
<button (click)="switch(this)" class="btn btn-sm btn-outline-primary mr-1 ">Switch</button> | |
<button (click)="edit(this)" class="btn btn-sm btn-outline-danger mr-1">Edit</button> | |
<div> | |
</div> | |
</div> | |
</div> | |
`, | |
}) | |
export class WidgetComponent implements OnInit { | |
@Input() title: string; | |
count: number; | |
viewRef: ViewRef; | |
switch: Function; | |
edit: Function; | |
ngOnInit(): void { | |
this.count = 0; | |
} | |
increase() { | |
this.count++; | |
} | |
decrement() { | |
this.count--; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment