Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 应用程序中的文件管理器出现问题-文件夹和文件夹不可见_Angular_Typescript - Fatal编程技术网

Angular 应用程序中的文件管理器出现问题-文件夹和文件夹不可见

Angular 应用程序中的文件管理器出现问题-文件夹和文件夹不可见,angular,typescript,Angular,Typescript,我最终实现了教程中的文件管理器。 我在vscode和chrome调试工具中没有任何错误,有人可以告诉我为什么我的文件夹不可见 我不知道如何修理它。我会给你你需要的一切:) 更新1 我认为问题在于从外部导入样式。我只是创建了index.html和style.scss-这需要以某种方式连接吗 Index.html: <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

我最终实现了教程中的文件管理器。 我在vscode和chrome调试工具中没有任何错误,有人可以告诉我为什么我的文件夹不可见

我不知道如何修理它。我会给你你需要的一切:)

更新1 我认为问题在于从外部导入样式。我只是创建了index.html和style.scss-这需要以某种方式连接吗

Index.html:

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
更新2 I添加mp-file-explorer.component文件:

*.ts:

更新3 我想补充更多细节:

main.component.ts

import { MatSidenav, MatGridTileHeaderCssMatStyler } from '@angular/material';
import { Component, ViewChild, ViewEncapsulation, OnDestroy, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreService, CoreHelper, Indicator } from 'mpcore';
import { Subject, Observable } from 'rxjs';
import { takeWhile, takeUntil } from 'rxjs/operators';
import { MpFileElement } from 'projects/mpcore-app/lib-common/src/lib/mp-file-explorer/models/mp-file-element.model';
import { MpFileService } from 'projects/mpcore-app/lib-common/src/lib/mp-file-explorer/services/file.service';

@Component({
  // tslint:disable-next-line:component-selector
  selector: 'main-root',
  templateUrl: './main.component.html',
  encapsulation: ViewEncapsulation.None
})
export class MainComponent implements OnDestroy, OnInit {
  public _onDestroy = new Subject<void>();
  protected isInitialized = false;

  public applicationName: string;
  public selectedItems: number;
  public took: number | null = null;
  public customText: string | null = null;
  public allItems: number;
  public openCloseMenu = 'closeMenu';
  public MainIndicator: Indicator = new Indicator();

  public fileElements: Observable<MpFileElement[]> = new Observable<MpFileElement[]>();

  currentRoot!: MpFileElement;
  currentPath!: string;
  canNavigateUp!: boolean;

  @ViewChild('sidenav', { static: false }) sidenav: MatSidenav | null = null;
  public constructor(

    private coreService: CoreService,
    private translate: TranslateService,
    private fileService: MpFileService
    ) {
    this.canNavigateUp = false;
    this.isInitialized = true;
    this.coreService.applicationName = this.applicationName = 'file-manager';
    this.allItems = 0;
    this.selectedItems = 0;
    this.coreService.langChanged$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe(() => {
        this.translate.use(this.coreService.lang);
      });

    this.coreService.showUserPanel$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe((data) => {
        if (data) {
          (this.sidenav as MatSidenav).open();
        } else {
          (this.sidenav as MatSidenav).close();
        }
      });

    this.coreService.displayAllItems$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe((data) => {
        this.allItems = data;
      });

    this.coreService.displaySelectedItems$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe((data) => {
        this.selectedItems = data;
      });

    this.coreService.displayTook$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe((data) => {
        this.took = data;
      });

    this.coreService.displayCustomText$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe((data) => {
        this.customText = data;
      });

    this.coreService.showModulePanel$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe(() => {
        if (this.openCloseMenu === 'openMenu') {
          this.openCloseMenu = 'closeMenu';
        } else {
          this.openCloseMenu = 'openMenu';
        }
      });

    this.coreService.showIndicator$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe((message) => {
        if (CoreHelper.hasValue(message)) {
          this.MainIndicator.ShowBusy(message);
        } else {
          this.MainIndicator.HideBusy();
        }
      });
  }

  public ngOnDestroy(): void {
    this.isInitialized = false;
    this._onDestroy.next();
    this._onDestroy.complete();
  }

  public openCoreModuleList() {
    if (this.openCloseMenu === 'openMenu') {
      this.openCloseMenu = 'closeMenu';
    } else {
      this.openCloseMenu = 'openMenu';
    }
  }

  ngOnInit() {
    const folderA = this.fileService.add({ name: 'Folder A', isFolder: true, parent: 'root' });

    if ( folderA.id !== undefined ) {
      this.fileService.add({ name: 'Folder B', isFolder: true, parent: 'root' });
      this.fileService.add({ name: 'Folder C', isFolder: true, parent: folderA.id });
      this.fileService.add({ name: 'File A', isFolder: false, parent: 'root' });
      this.fileService.add({ name: 'File B', isFolder: false, parent: 'root' });
    }

    this.updateFileElementQuery();
  }

  addFolder(folder: { name: string }) {
    if ( this.currentRoot !== undefined && this.currentRoot.id ) {
      this.fileService.add({ isFolder: true, name: folder.name, parent: this.currentRoot ? this.currentRoot.id : 'root' });
    }

    this.updateFileElementQuery();
  }

  removeElement(element: MpFileElement) {
    if ( element.id !== undefined ) {
      this.fileService.delete(element.id);
    }
    this.updateFileElementQuery();
  }

  moveElement(event: { element: MpFileElement; moveTo: MpFileElement }) {
    if ( event.element.id !== undefined ) {
      this.fileService.update(event.element.id, { parent: event.moveTo.id });
    }
    this.updateFileElementQuery();
  }

  renameElement(element: MpFileElement) {
    if ( element.id !== undefined ) {
      this.fileService.update(element.id, { name: element.name });
    }
    this.updateFileElementQuery();
  }

  updateFileElementQuery() {
    if ( this.currentRoot !== undefined && this.currentRoot.id ) {
      this.fileElements = this.fileService.queryInFolder(this.currentRoot ? this.currentRoot.id : 'root');
    }
  }

  navigateUp() {
    if (this.currentRoot && this.currentRoot.parent === 'root') {
      this.currentRoot.name = 'root';
      this.canNavigateUp = false;
      this.updateFileElementQuery();
    } else {
      if ( this.currentRoot.parent !== undefined ) {
        const currentRootTemp = this.fileService.get(this.currentRoot.parent);
        if (currentRootTemp !== undefined) {
          this.currentRoot = currentRootTemp;
        }
      }
      this.updateFileElementQuery();
    }
    this.currentPath = this.popFromPath(this.currentPath);
  }

  navigateToFolder(element: MpFileElement) {
    this.currentRoot = element;
    this.updateFileElementQuery();
    if ( element.name !== undefined ) {
      this.currentPath = this.pushToPath(this.currentPath, element.name);
    }
    this.canNavigateUp = true;
  }

  pushToPath(path: string, folderName: string) {
    let p = path ? path : '';
    p += `${folderName}/`;
    return p;
  }

  popFromPath(path: string) {
    let p = path ? path : '';
    const split = p.split('/');
    split.splice(split.length - 2, 1);
    p = split.join('/');
    return p;
  }
}
main.component.ts
从“@angular/material”导入{MatSidenav,MatGridTileHeaderCssMatStyler};
从“@angular/core”导入{Component,ViewChild,viewenclosuration,onestroy,OnInit};
从'@ngx translate/core'导入{TranslateService};
从“mpcore”导入{CoreService,coreheloper,Indicator};
从“rxjs”导入{Subject,observeable};
从'rxjs/operators'导入{takeWhile,takeUntil};
从“projects/mpcore app/lib common/src/lib/mp file explorer/models/mp file element.model”导入{MpFileElement};
从“projects/mpcore app/lib common/src/lib/mp file explorer/services/file.service”导入{MpFileService};
@组成部分({
//tslint:禁用下一行:组件选择器
选择器:'主根',
templateUrl:'./main.component.html',
封装:视图封装。无
})
导出类MainComponent实现OnDestroy、OnInit{
public_ondestory=新主题();
保护初始值=假;
公共应用程序名称:字符串;
公共选择项:编号;
公共密钥:number | null=null;
公共自定义文本:字符串| null=null;
公共项目:数量;
public openCloseMenu='closeMenu';
公共主指示器:指示器=新指示器();
public fileElements:Observable=新的Observable();
currentRoot!:MpFileElement;
currentPath!:字符串;
canNavigateUp!:布尔值;
@ViewChild('sidenav',{static:false})sidenav:MatSidenav | null=null;
公共构造函数(
私有coreService:coreService,
私人翻译:翻译服务,
私有文件服务:MpFileService
) {
this.canNavigateUp=false;
this.isInitialized=真;
this.coreService.applicationName=this.applicationName='文件管理器';
此参数为0.allItems=0;
this.selectedItems=0;
此.coreService.lang已更改$
.烟斗(
takeWhile(()=>this.i初始化),
takeUntil(这个)
)
.订阅(()=>{
this.translate.use(this.coreService.lang);
});
this.coreService.showUserPanel$
.烟斗(
takeWhile(()=>this.i初始化),
takeUntil(这个)
)
.订阅((数据)=>{
如果(数据){
(此.sidenav为MatSidenav).open();
}否则{
(此.sidenav为MatSidenav).close();
}
});
this.coreService.displayAllItems$
.烟斗(
takeWhile(()=>this.i初始化),
takeUntil(这个)
)
.订阅((数据)=>{
this.allItems=数据;
});
this.coreService.displaySelectedItems$
.烟斗(
takeWhile(()=>this.i初始化),
takeUntil(这个)
)
.订阅((数据)=>{
this.selectedItems=数据;
});
this.coreService.displayTake$
.烟斗(
takeWhile(()=>this.i初始化),
takeUntil(这个)
)
.订阅((数据)=>{
this.take=数据;
});
this.coreService.displayCustomText$
.烟斗(
takeWhile(()=>this.i初始化),
takeUntil(这个)
)
.订阅((数据)=>{
this.customText=数据;
});
this.coreService.showModulePanel$
.烟斗(
takeWhile(()=>this.i初始化),
takeUntil(这个)
)
.订阅(()=>{
如果(this.openCloseMenu==='openMenu'){
this.openCloseMenu='closeMenu';
}否则{
this.openCloseMenu='openMenu';
}
});
this.coreService.showIndicator$
.烟斗(
takeWhile(()=>this.i初始化),
takeUntil(这个)
)
.订阅((消息)=>{
if(coreheloper.hasValue(消息)){
此.main指示器.ShowBusy(消息);
}否则{
this.maindicator.HideBusy();
}
});
}
公共Ngondestory():void{
this.i初始化=错误;
这个;
这个。_ondestory.complete();
}
公共openCoreModuleList(){
如果(this.openCloseMenu==='openMenu'){
this.openCloseMenu='closeMenu';
}否则{
this.openCloseMenu='openMenu';
}
}
恩戈尼尼特(){
const folderA=this.fileService.add({name:'Folder A',isFolder:true,parent:'root'});
如果(folderA.id!==未定义){
this.fileService.add({name:'Folder B',isFolder:true,parent:'root'});
this.fileService.add({name:'Folder C',isFolder:true,parent:folderA.id});
this.fileService.add({name:'filea',isFolder:false,parent:'root'});
this.fileService.add({name:'fileb',isFolder:false,parent:'root'});
}
this.updateFileElementQuery();
}
addFolder(文件夹:{name:string}){
if(this.currentRoot!==undefined&&this.currentRoot.id){
this.fileService.add({isFolder:true,name:folder.name,父项:this.currentRoot?this.currentRoot.id:'root'});
}
this.updateFileElementQuery();
}
removeElement(元素:MpFileElement){
if(element.id!==未定义){
this.fileService.delete(element.id);
}
this.updateFileElementQuery();
}
moveElement(事件:{element:MpFileElement;moveTo:MpFileElement}){
if(event.element.id!==未定义){
this.fileService.update(event.element.id,{parent:event.moveTo.id});
}
this.updateFileElementQuery();
}
重命名元素(元素:MpFileElement){
如果(ele
import { Component, Input, Output, EventEmitter } from '@angular/core';
import { MpFileElement } from '../../models/mp-file-element.model';
import { MatMenuTrigger } from '@angular/material';
import { MatDialog } from '@angular/material/dialog';
import { MpNewFolderDialogComponent } from '../messages/mp-new-folder-dialog/mp-new-folder-dialog.component';
import { MpRenameDialogComponent } from '../messages/mp-rename-dialog/mp-rename-dialog.component';

@Component({
  selector: 'lib-mp-file-explorer',
  templateUrl: './mp-file-explorer.component.html',
  styleUrls: ['./mp-file-explorer.component.scss']
})
export class MpFileExplorerComponent {

  @Input() fileElements: MpFileElement[] = [
    {
      id: '',
      isFolder: false,
      name: '',
      parent: ''
    }
  ];
  @Input() canNavigateUp = '';
  @Input() path = '';

  @Output() folderAdded = new EventEmitter<{ name: string}>();
  @Output() elementRemoved = new EventEmitter<MpFileElement>();
  @Output() elementRenamed = new EventEmitter<MpFileElement>();
  @Output() elementMoved = new EventEmitter<{
    element: MpFileElement,
    moveTo: MpFileElement
  }>();
  @Output() navigatedDown = new EventEmitter<MpFileElement>();
  @Output() navigatedUp = new EventEmitter();

  constructor(public dialog: MatDialog) {}

  deleteElement(element: MpFileElement) {
    this.elementRemoved.emit(element);
  }

  navigate(element: MpFileElement) {
    if (element.isFolder) {
      this.navigatedDown.emit();
    }
  }

  navigateUp() {
    this.navigatedUp.emit();
  }

  moveElement(element: MpFileElement, moveTo: MpFileElement) {
    this.elementMoved.emit({
      element,
      moveTo
    });
  }

  openNewFolderDialog() {
    const dialogRef = this.dialog.open(MpNewFolderDialogComponent);
    dialogRef.afterClosed().subscribe(res => {
      if (res) {
        this.folderAdded.emit({ name: res });
      }
    });
  }

  openRenameDialog(element: MpFileElement) {
    const dialogRef = this.dialog.open(MpRenameDialogComponent);
    dialogRef.afterClosed().subscribe(res => {
      if (res) {
        element.name = res;
        this.elementRenamed.emit(element);
      }
    });
  }

  openMenu(event: MouseEvent, element: MpFileElement, viewChild: MatMenuTrigger) {
    event.preventDefault();
    viewChild.openMenu();
  }
}
<mat-toolbar>
  <mat-icon *ngIf="canNavigateUp" class="pointer" (click)="navigateUp()">
    arrow_back
  </mat-icon>
  <span style="margin-left: 8px"> {{path || 'Files'}} </span>
  <span class="spacer"></span>
  <mat-icon class="pointer" (click)="openNewFolderDialog()">
    create_new_folder
  </mat-icon>
</mat-toolbar>

<div
  class="container"
  fxFlex
  fxLayout="row"
  fxLayoutAlign="space-between stretch"
>
    <div class="content" fxFlex fxLayout="row">
      <mat-grid-list cols="8" rowHeight="100px" fxFlex>
        <mat-grid-tile
          *ngFor="let element of fileElements"
          class="file-or-folder"
        >
          <span
            [matMenuTriggerFor]="rootMenu"
            [matMenuTriggerData]="{element: element}"
            #menuTrigger="matMenuTrigger"
          >
          </span>
          <div
            fxLayout="column"
            fxLayoutAlign="space-between center"
            (click)="navigate(element)"
            (contextmenu)="openMenu($event, menuTrigger)"
          >
            <mat-icon
              color="primary"
              class="file-or-folder-icon pointer"
              *ngIf="element.isFolder"
            >
              folder
            </mat-icon>
            <mat-icon
              color="primary"
              class="file-or-folder-icon pointer"
              *ngIf="!element.isFolder"
            >
              insert_drive_file
            </mat-icon>

            <span>{{element.name}}</span>
          </div>
        </mat-grid-tile>
      </mat-grid-list>
    </div>
  </div>

  <mat-menu #rootMenu="matMenu" [overlapTrigger]="false">
    <ng-template matMenuContent let-element="element">
      <button
        mat-menu-item
        [matMenuTriggerFor]="moveToMenu"
        [matMenuTriggerData]="{self: element}"
      >
        <mat-icon>open_with</mat-icon>
        <span>Move To</span>
      </button>
      <button mat-menu-item (click)="openRenameDialog(element)">
        <mat-icon>edit</mat-icon>
        <span>Rename</span>
      </button>
      <button mat-menu-item (click)="deleteElement(element)">
        <mat-icon>delete</mat-icon>
        <span>Delete</span>
      </button>
    </ng-template>
  </mat-menu>

  <mat-menu #moveToMenu="matMenu">
    <ng-template matMenuContent let-self="self">
      <ng-container *ngFor="let element of fileElements">
        <button
          *ngIf="element.isFolder && element.id !== self.id"
          mat-menu-item
          (click)="moveElement(self, element)"
        >
          {{element.name}}
        </button>
      </ng-container>
    </ng-template>
  </mat-menu>
:host {
  height: 50%;
  width: 50%;
  display: flex;
  flex-direction: column;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  margin-left: 25%;
  margin-top: 25%;
}

.file-or-folder {
  padding: 8px;
  overflow: hidden;
}

.file-or-folder-icon {
  width: 50px;
  height: 50px;
  font-size: 50px;
}

.pointer {
  cursor: pointer;
}

.spacer {
  flex: 1 1 auto;
}
main.component.ts

import { MatSidenav, MatGridTileHeaderCssMatStyler } from '@angular/material';
import { Component, ViewChild, ViewEncapsulation, OnDestroy, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CoreService, CoreHelper, Indicator } from 'mpcore';
import { Subject, Observable } from 'rxjs';
import { takeWhile, takeUntil } from 'rxjs/operators';
import { MpFileElement } from 'projects/mpcore-app/lib-common/src/lib/mp-file-explorer/models/mp-file-element.model';
import { MpFileService } from 'projects/mpcore-app/lib-common/src/lib/mp-file-explorer/services/file.service';

@Component({
  // tslint:disable-next-line:component-selector
  selector: 'main-root',
  templateUrl: './main.component.html',
  encapsulation: ViewEncapsulation.None
})
export class MainComponent implements OnDestroy, OnInit {
  public _onDestroy = new Subject<void>();
  protected isInitialized = false;

  public applicationName: string;
  public selectedItems: number;
  public took: number | null = null;
  public customText: string | null = null;
  public allItems: number;
  public openCloseMenu = 'closeMenu';
  public MainIndicator: Indicator = new Indicator();

  public fileElements: Observable<MpFileElement[]> = new Observable<MpFileElement[]>();

  currentRoot!: MpFileElement;
  currentPath!: string;
  canNavigateUp!: boolean;

  @ViewChild('sidenav', { static: false }) sidenav: MatSidenav | null = null;
  public constructor(

    private coreService: CoreService,
    private translate: TranslateService,
    private fileService: MpFileService
    ) {
    this.canNavigateUp = false;
    this.isInitialized = true;
    this.coreService.applicationName = this.applicationName = 'file-manager';
    this.allItems = 0;
    this.selectedItems = 0;
    this.coreService.langChanged$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe(() => {
        this.translate.use(this.coreService.lang);
      });

    this.coreService.showUserPanel$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe((data) => {
        if (data) {
          (this.sidenav as MatSidenav).open();
        } else {
          (this.sidenav as MatSidenav).close();
        }
      });

    this.coreService.displayAllItems$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe((data) => {
        this.allItems = data;
      });

    this.coreService.displaySelectedItems$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe((data) => {
        this.selectedItems = data;
      });

    this.coreService.displayTook$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe((data) => {
        this.took = data;
      });

    this.coreService.displayCustomText$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe((data) => {
        this.customText = data;
      });

    this.coreService.showModulePanel$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe(() => {
        if (this.openCloseMenu === 'openMenu') {
          this.openCloseMenu = 'closeMenu';
        } else {
          this.openCloseMenu = 'openMenu';
        }
      });

    this.coreService.showIndicator$
      .pipe(
        takeWhile(() => this.isInitialized),
        takeUntil(this._onDestroy)
      )
      .subscribe((message) => {
        if (CoreHelper.hasValue(message)) {
          this.MainIndicator.ShowBusy(message);
        } else {
          this.MainIndicator.HideBusy();
        }
      });
  }

  public ngOnDestroy(): void {
    this.isInitialized = false;
    this._onDestroy.next();
    this._onDestroy.complete();
  }

  public openCoreModuleList() {
    if (this.openCloseMenu === 'openMenu') {
      this.openCloseMenu = 'closeMenu';
    } else {
      this.openCloseMenu = 'openMenu';
    }
  }

  ngOnInit() {
    const folderA = this.fileService.add({ name: 'Folder A', isFolder: true, parent: 'root' });

    if ( folderA.id !== undefined ) {
      this.fileService.add({ name: 'Folder B', isFolder: true, parent: 'root' });
      this.fileService.add({ name: 'Folder C', isFolder: true, parent: folderA.id });
      this.fileService.add({ name: 'File A', isFolder: false, parent: 'root' });
      this.fileService.add({ name: 'File B', isFolder: false, parent: 'root' });
    }

    this.updateFileElementQuery();
  }

  addFolder(folder: { name: string }) {
    if ( this.currentRoot !== undefined && this.currentRoot.id ) {
      this.fileService.add({ isFolder: true, name: folder.name, parent: this.currentRoot ? this.currentRoot.id : 'root' });
    }

    this.updateFileElementQuery();
  }

  removeElement(element: MpFileElement) {
    if ( element.id !== undefined ) {
      this.fileService.delete(element.id);
    }
    this.updateFileElementQuery();
  }

  moveElement(event: { element: MpFileElement; moveTo: MpFileElement }) {
    if ( event.element.id !== undefined ) {
      this.fileService.update(event.element.id, { parent: event.moveTo.id });
    }
    this.updateFileElementQuery();
  }

  renameElement(element: MpFileElement) {
    if ( element.id !== undefined ) {
      this.fileService.update(element.id, { name: element.name });
    }
    this.updateFileElementQuery();
  }

  updateFileElementQuery() {
    if ( this.currentRoot !== undefined && this.currentRoot.id ) {
      this.fileElements = this.fileService.queryInFolder(this.currentRoot ? this.currentRoot.id : 'root');
    }
  }

  navigateUp() {
    if (this.currentRoot && this.currentRoot.parent === 'root') {
      this.currentRoot.name = 'root';
      this.canNavigateUp = false;
      this.updateFileElementQuery();
    } else {
      if ( this.currentRoot.parent !== undefined ) {
        const currentRootTemp = this.fileService.get(this.currentRoot.parent);
        if (currentRootTemp !== undefined) {
          this.currentRoot = currentRootTemp;
        }
      }
      this.updateFileElementQuery();
    }
    this.currentPath = this.popFromPath(this.currentPath);
  }

  navigateToFolder(element: MpFileElement) {
    this.currentRoot = element;
    this.updateFileElementQuery();
    if ( element.name !== undefined ) {
      this.currentPath = this.pushToPath(this.currentPath, element.name);
    }
    this.canNavigateUp = true;
  }

  pushToPath(path: string, folderName: string) {
    let p = path ? path : '';
    p += `${folderName}/`;
    return p;
  }

  popFromPath(path: string) {
    let p = path ? path : '';
    const split = p.split('/');
    split.splice(split.length - 2, 1);
    p = split.join('/');
    return p;
  }
}
<div class="full-height fxcol" [ngClass]="'side-menu-disabled'">
  <core-top-panel [applicationName]="applicationName"></core-top-panel>
  <div class="fxgrow">
    <div class="core-main-window fxgrow fxcol">
      <mat-sidenav-container class="fxfill">
        <mat-sidenav #sidenav position="end" mode="over">
          <core-user-panel></core-user-panel>
        </mat-sidenav>
        <mp-indicator [indicator]="MainIndicator"></mp-indicator>

        <div class="full-height fxcol">
          <div style="padding: 100px; height: 100%; box-sizing: border-box;">
            <mat-card style="height: 100%; box-sizing: border-box; padding:0">
              <lib-mp-file-explorer [fileElements]="fileElements | async" [path]="currentPath" [canNavigateUp]="canNavigateUp" (folderAdded)="addFolder($event)"
                (elementRemoved)="removeElement($event)" (navigatedDown)="navigateToFolder($event)" (navigatedUp)="navigateUp()" (elementRenamed)="renameElement($event)"
                (elementMoved)="moveElement($event)">
              </lib-mp-file-explorer>
            </mat-card>
          </div>
        </div>
      </mat-sidenav-container>
      <core-footer [allItems]="allItems" [selectedItems]="selectedItems" [took]="took" [customText]="customText"> </core-footer>
    </div>
  </div>
</div>
import { Injectable } from '@angular/core';

import { v4 } from 'uuid';
import { MpFileElement } from '../models/mp-file-element.model';
import { Observable } from 'rxjs/internal/Observable';
import { BehaviorSubject } from 'rxjs';
import { NullTemplateVisitor } from '@angular/compiler';

export interface IFileService {
    add(fileElement: MpFileElement): MpFileElement;
    delete(id: string): void;
    update(id: string, update: Partial<MpFileElement>): void;
    queryInFolder(folderId: string): Observable<MpFileElement[]>;
    get(id: string): MpFileElement | void;
}

@Injectable()
export class MpFileService implements IFileService {

    constructor() {}
    private map = new Map<string, MpFileElement>()

    private querySubject: BehaviorSubject<MpFileElement[]> = new BehaviorSubject<MpFileElement[]>([]);

    add(fileElement: MpFileElement): MpFileElement {
        fileElement.id = v4();
        this.map.set(fileElement.id, this.clone(fileElement));
        return fileElement;
    }

    delete(id: string): void {
        this.map.delete(id);
    }

    update(id: string, update: Partial<MpFileElement>): void {
        let element = this.map.get(id);
        element = Object.assign(element, update);
        if ( element.id !== undefined ) {
            this.map.set(element.id, element);
        }
    }
    queryInFolder(folderId: string): Observable<MpFileElement[]> {
        const result: MpFileElement[] = [];
        this.map.forEach(element => {
            if (element.parent === folderId) {
                result.push(this.clone(element));
            }
        });
        if (!this.querySubject) {
            this.querySubject = new BehaviorSubject(result);
        } else {
            this.querySubject.next(result);
        }
        return this.querySubject.asObservable();
    }

    get(id: string): MpFileElement | undefined {
        if ( id !== undefined ) {
            return this.map.get(id);
        }
        return undefined;
    }

    clone(element: MpFileElement): MpFileElement {
        return JSON.parse(JSON.stringify(element));
    }
}
@Input() fileElements: MpFileElement[] = [
    {
      id: '',
      isFolder: false,
      name: '',
      parent: ''
    }
  ];
updateFileElementQuery() {
    if ( this.currentRoot !== undefined && this.currentRoot.id ) {
      this.fileElements = this.fileService.queryInFolder(this.currentRoot ? this.currentRoot.id : 'root');
    }
  }