salix/front/core/components/slot/index.js

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);