Angular 在生产环境中将类型保存到localStorage并从中恢复

Angular 在生产环境中将类型保存到localStorage并从中恢复,angular,typescript,local-storage,Angular,Typescript,Local Storage,我构建了一个可停靠面板解决方案,希望将布局存储到localStorage,以便在重新加载页面时再次使用它。这在我的本地主机上起到了很好的作用。以下是最重要的模型以及我如何使用它们: export class DockTreeNode { parent: DockTreeContainer; // methods.. } export class DockTreePanel extends DockTreeNode { type: Type<DockablePanel>;

我构建了一个可停靠面板解决方案,希望将布局存储到
localStorage
,以便在重新加载页面时再次使用它。这在我的本地主机上起到了很好的作用。以下是最重要的模型以及我如何使用它们:

export class DockTreeNode {
  parent: DockTreeContainer;
  // methods..
}

export class DockTreePanel extends DockTreeNode {
  type: Type<DockablePanel>;
  args: DockArguments;
  movable: boolean;
}

export class DockTreeContainer extends DockTreeNode {
  private orientation: Orientation;
  private left: DockTreeNode;
  private right: DockTreeNode;
}

dockTree: DockTreeNode = new DockTreeContainer(
  new DockTreePanel(
    TestPanelComponent,
    null,
    false
  ),
  new DockTreePanel(
    BovenbouwingComponent,
    null,
    true
  ),
  Orientation.horizontal
);
但是,当我将其提交到svn存储库,Jenkins使用
ng build--prod
构建并启动运行该构建的Docker容器时,type的保存值将是完全无用的:

{
  "left": {
    "type": "",
  },
  "right": {
    "type": "n",
  }
  // More stuff
}

我认为这与TypeScript将所有内容编译为JavaScript AOT有关,因此在运行代码时,类型实际上并不存在。但是,我不明白,仅仅通过使用
typeMap这个问题主要与本地主机有关,它在本地主机上是否起作用

只要开发人员知道后果,就可以使用函数
name
。在Node.js这样的环境中,依赖它是相当安全的。如果代码应该缩小(通常在客户端JS中),函数名也将缩小

为了确保存储正确的类名并能够还原它们,类应该明确地映射到它们的名称(也可以有多个同名函数)

类应该具有标识它们的静态属性<代码>名称
不能安全地重新定义,并且。使名称唯一可能更安全,因为这样无法安全存储的类会导致错误。实现这一点的一种方便方法是类装饰器

另一种方法是拥有已知类名的映射:

const classMap = {
  TestPanelComponent,
  ...
};

它可以在存储类时引用。同样,如果一个类在映射中不存在,它应该会导致一个错误。

我解决了它。我在问题中遗漏了一个关键部分:

private typeMap: Map<string, Type<DockablePanel>> = new Map();

  constructor(@Inject('panelTypes') private panelTypes: Type<DockablePanel>[]) {
    for (let i = 0; i < panelTypes.length; i++) {
      this.typeMap.set(panelTypes[i].name, panelTypes[i]);
    }
  }
private-typeMap:Map=newmap();
构造函数(@Inject('panelTypes')私有panelTypes:Type[]){
for(设i=0;i
在这里,我使用类型的名称作为键将面板的类型放入一个映射中。解决方案是放弃这一点,只使用panelTypes本身:

constructor(@Inject('panelTypes') private panelTypes: Type<DockablePanel>[]) {  }

public setDefaultDockTree(dockTree: DockTreeNode): void {
  // more code
  const stored = JSON.parse(storageItem, (key, value) => {
    if (key === 'type') {
      // The changed part:
      const panel: Type<DockablePanel> = this.panelTypes.find((panelType: Type<DockablePanel>) => {
        return panelType.name === value;
      });
      if (!panel) {
        console.log('Couldn\'t find paneltype ' + value);
      } else {
        return panel;
      }
    } else {
      return value;
    }
  });
  // More code
}
构造函数(@Inject('panelTypes')私有panelTypes:Type[]){
public setDefaultDockTree(dockTree:DockTreeNode):无效{
//更多代码
const stored=JSON.parse(storageItem,(键,值)=>{
如果(键=='type'){
//更改部分:
const panel:Type=this.panelTypes.find((panelType:Type)=>{
返回panelType.name==值;
});
如果(!面板){
log('找不到paneltype'+值);
}否则{
返回面板;
}
}否则{
返回值;
}
});
//更多代码
}

在图中没有映射的情况下,我只需使用Type.name属性来查找正确的类型。

我有一个类映射:
const panels:Type[]=[BovenbouwingComponent、KosteNodeBouWingComponent、TestPanelComponent、FormPanelComponent]它没有很好的用途,因为您不存储类名,只存储对类函数的引用
const classMap={TestPanelComponent}
const classMap={TestPanelComponent:TestPanelComponent}
的快捷方式。类名存储为属性。
private typeMap: Map<string, Type<DockablePanel>> = new Map();

  constructor(@Inject('panelTypes') private panelTypes: Type<DockablePanel>[]) {
    for (let i = 0; i < panelTypes.length; i++) {
      this.typeMap.set(panelTypes[i].name, panelTypes[i]);
    }
  }
constructor(@Inject('panelTypes') private panelTypes: Type<DockablePanel>[]) {  }

public setDefaultDockTree(dockTree: DockTreeNode): void {
  // more code
  const stored = JSON.parse(storageItem, (key, value) => {
    if (key === 'type') {
      // The changed part:
      const panel: Type<DockablePanel> = this.panelTypes.find((panelType: Type<DockablePanel>) => {
        return panelType.name === value;
      });
      if (!panel) {
        console.log('Couldn\'t find paneltype ' + value);
      } else {
        return panel;
      }
    } else {
      return value;
    }
  });
  // More code
}