82 lines
1.9 KiB
JavaScript
82 lines
1.9 KiB
JavaScript
import ngModule from '../../module';
|
|
import './portal';
|
|
import './style.scss';
|
|
|
|
export class Slot {
|
|
constructor($element, vnSlotService) {
|
|
this.$element = $element;
|
|
this.vnSlotService = vnSlotService;
|
|
this.$content = null;
|
|
}
|
|
|
|
$onDestroy() {
|
|
this.unregister();
|
|
}
|
|
|
|
set name(value) {
|
|
this.unregister();
|
|
this._name = value;
|
|
this.vnSlotService.slots[value] = this;
|
|
}
|
|
|
|
get name() {
|
|
return this._name;
|
|
}
|
|
|
|
unregister() {
|
|
if (this.name)
|
|
this.vnSlotService.slots[this.name] = undefined;
|
|
}
|
|
|
|
setContent($content) {
|
|
if (this.$content) {
|
|
this.$content.detach();
|
|
this.$content = null;
|
|
}
|
|
|
|
this.$content = $content;
|
|
if (this.$content) this.$element.append($content);
|
|
this.$element[0].style.display = $content ? 'block' : 'none';
|
|
}
|
|
}
|
|
Slot.$inject = ['$element', 'vnSlotService'];
|
|
|
|
ngModule.vnComponent('vnSlot', {
|
|
controller: Slot,
|
|
bindings: {
|
|
name: '@?'
|
|
}
|
|
});
|
|
|
|
export class SlotService {
|
|
constructor() {
|
|
this.stacks = {};
|
|
this.slots = {};
|
|
}
|
|
|
|
push(slot, $transclude) {
|
|
if (!this.stacks[slot]) this.stacks[slot] = [];
|
|
this.stacks[slot].unshift($transclude);
|
|
this.refreshContent(slot);
|
|
}
|
|
|
|
pop(slot) {
|
|
let $content = this.stacks[slot].shift();
|
|
this.refreshContent(slot);
|
|
if ($content && typeof $content == 'object')
|
|
$content.remove();
|
|
}
|
|
|
|
refreshContent(slot) {
|
|
if (!this.slots[slot]) return;
|
|
let $content = this.stacks[slot][0];
|
|
if (typeof $content == 'function') {
|
|
$content(clone => {
|
|
$content = this.stacks[slot][0] = clone;
|
|
});
|
|
}
|
|
this.slots[slot].setContent($content);
|
|
}
|
|
}
|
|
ngModule.service('vnSlotService', SlotService);
|