首页 > 解决方案 > 无法重置我在根中提供的单例服务

问题描述

我制作了一个单例服务,可以在视图之间更新数据。所以我在视图中将它们用作 DTO。这个主单例服务引用了其他单例服务。在主服务中,我有一个 reset() 函数,它应该将主服务上的属性返回到它们的原始值并引用外围单例服务 reset() 方法。不幸的是,它没有做后面的部分,而是用一个新属性覆盖主单例服务对外围单例服务的引用(与放在主服务的构造函数中的引用相同),但必须以某种方式仍然访问该外围服务的方法,因此它知道将这个新属性设置为什么。

为什么它不能识别 org 构造函数中的 org ??? 在此处输入图像描述

为什么这种重置方法不起作用?有没有更好的方法/最佳实践来做到这一点?谢谢你。

下面我提供了主要的单例以及其中引用的单例。

如果我需要澄清,请告诉我。

主要单身人士

import { OrgAdmin } from './../org-admin.model';
import { Permission } from './../permission.model';
import { UserRequest } from "../user-request.model";
import { Customer } from "../customer.model";
import { SecurityProfileDto } from "../security-profile-dto";
import { Org } from "../org.model";
import { Injectable } from '@angular/core';


@Injectable({ providedIn: 'root' })
export class OrgViewModel {
  // current forms
  orgInfo: Org = this.org;
  currentOrgAdmin: UserRequest = this.user;
  currentSecProfile: SecurityProfileDto = this.secProf;

  // current mapping grid
  orgAdmins: UserRequest[] = [];
  customers: Customer[] = [];
  secProfiles: SecurityProfileDto[] = [];
  railroadfilters: string[] = [];


  orgAdminsValidity: string = 'invalid'; // invalid, incomplete, valid
  customersValidity: string = 'invalid'; // invalid, incomplete, valid
  secProfilesValidity: string = 'invalid'; // invalid, incomplete, valid
  filtersValidity: string = 'invalid'; // invalid, incomplete, valid

  // meta orgViewModel
  isFinalized: boolean = false;
  isNew: boolean = false;

  valid: boolean = false; // invalid, incomplete, valid
  done: boolean = false;

  constructor(
    private org: Org,
    private user: UserRequest,
    private orgAdmin: OrgAdmin,
    private secProf: SecurityProfileDto,
  ) { }

  reset() {
    this.org.reset();
    this.orgAdmin.reset();
    this.secProf.reset();
    this.orgAdmins = [];
    this.orgAdminsValidity = 'invalid'; // invalid, incomplete, valid
    this.customers = [];
    this.customersValidity = 'invalid'; // invalid, incomplete, valid
    this.secProfiles = [];
    this.secProfilesValidity = 'invalid'; // invalid, incomplete, valid
    this.railroadfilters = [];
    this.filtersValidity = 'invalid'; // invalid, incomplete, valid

    this.isFinalized = false;
    this.isNew = false;
    this.valid = false;
    this.done = false;
    console.log('orgVM Model : CLEARED ');
  }

  get complete() {
    return this.valid && this.done;
  }
}

组织单例

import { Injectable } from "@angular/core";

@Injectable({ providedIn: 'root' })
export class Org {
  id: string = "";
  orgName: string = "";
  active: boolean = false;
  isMakerChecker: boolean = false;
  addressLine1: string = "";
  addressLine2: string = "";
  state: string = "";
  city: string = "";
  postalCode: string = "";
  country: string = "";
  telephone: string = "";
  ext: string = "";
  domain: string = "";
  adminIds: string[];
  userIds: string[];
  securityProfileIds: string[];

  isActive: boolean = false;
  new: boolean = true;
  validity: boolean = false;
  complete: boolean = false;

  constructor() { }

  reset() {
    this.id = "";
    this.orgName = "";
    this.active = false;
    this.isMakerChecker = false;
    this.addressLine1 = "";
    this.addressLine2 = "";
    this.state = "";
    this.city = "";
    this.postalCode = "";
    this.country = "";
    this.telephone = "";
    this.ext = "";
    this.domain = "";
    this.adminIds = [];
    this.userIds = [];
    this.securityProfileIds = [];

    this.isActive = false;
    this.new = true;
    this.validity = false;
    this.complete = false;
  }
}

用户请求单例

import { Injectable } from "@angular/core";
import { UserReqValidStateService } from "../services/UserManagement/UserReqValidState.service";

@Injectable({ providedIn: 'root' })
export class UserRequest {
  id: string = "";
  userType: number = 0;
  firstName: string = "";
  lastName: string = "";
  cellPhone: string = "";
  officePhone: string = "";
  ext: string = "";
  fax: string = "";
  country: string = "";
  state: string = "";
  city: string = "";
  requesterId: string = "";
  orgId: string = "";
  supervisorId: string = "";
  securityProfileIds: string[] = [];
  emailAddress: string = "";

  isActive: boolean = false;
  userState: number = 0; // this is mainly for backend. 0 = submitted, 1 = approved, 2 = completed... in the future 3 = submittedButFailed
  new: boolean = true;
  validity: boolean = false;
  complete: boolean = false;

  constructor(private validstate: UserReqValidStateService) { }

  reset() {
    this.id = "";
    this.userType = 0;
    this.firstName = "";
    this.lastName = "";
    this.cellPhone = "";
    this.officePhone = "";
    this.ext = "";
    this.fax = "";
    this.country = "";
    this.state = "";
    this.city = "";
    this.requesterId = "";
    this.orgId = "";
    this.supervisorId = "";
    this.securityProfileIds = [];
    this.emailAddress = "";

    this.isActive = false;
    this.userState = 0; // this is mainly for the backend Control layer. 0 = submitted, 1 = approved, 2 = completed... in the future 3 = submittedButFailed
    this.new = true;
    this.validity = false;
    this.complete = false;


    this.validstate.stateCompUserInfoValid.subscribe(userInfoValid => this.validity = userInfoValid);


    console.log('USER REQUEST SINGLETON RESET');
  }
}

组织管理员单例

import { UserRequest } from "./user-request.model";

// THIS IS THE SAME AS USER REQUEST but we want to segrate the persistance in memory here

export class OrgAdmin extends UserRequest {

}

安全配置文件单例

import { Permission } from "./permission.model";
import { Injectable } from "@angular/core";

@Injectable({ providedIn: 'root' })
export class SecurityProfileDto {
  id: string = "";
  name: string = "";
  customerCodes: string[] = [];
  permissionCodes: string[] = [];
  orgId: string = "";

  new: boolean = true;
  validity: string = 'invalid';

  constructor() {

  }

  reset() {
    this.id = "";
    this.name = "";
    this.customerCodes = [];
    this.permissionCodes = [];
    this.orgId = "";
    this.new = true;
    this.validity = 'invalid';
    console.log('SEC PROFILE RESET');
  }

}

组织管理组件(我知道我需要重构...截止日期)

import { Org } from './../../../shared/models/org.model';
import { SecurityProfileDto } from './../../../shared/models/security-profile-dto';
import { SecProfService } from './../../../shared/services/webapi/sec-prof.service';
import { OrgViewModel } from './../../../shared/models/org/org-view.model';
import { Component, OnInit, DoCheck, OnDestroy } from '@angular/core';

import { slideToRight } from '../../../router.animations';
import { AgGridAbstractService } from '../../../shared/components/ag-grid-abstract/ag-grid-abstract';
import { GridAdminsRenderer } from '../../../shared/components/grid-admins/grid-admins.component';
import { GridStatusRenderer } from '../../../shared/components/grid-status/grid-status.component';
import { ViewMoreRenderer } from '../../../shared/components/grid-view-more-org/view-more.component';
import { BreadcrumbService } from '../../../shared/services/Nav/Breadcrumb.service';
import { OrgViewStateService } from '../../../shared/services/OrgManagement/OrgState.service';
import { OrgsService } from '../../../shared/services/webapi/orgs.service';
import { GlobalEvent$Service } from '../../../shared/services/global-event$.service';
import { UserRequestService } from '../../../shared/services/webapi/user-request.service';
import { UserRequest } from '../../../shared/models/user-request.model';
import { GridSecprofilesUserRenderer } from '../../../shared/components/grid/grid-secprofiles-user/grid-secprofiles-user.component';
import { GridSecprofilesOrgRenderer } from '../../../shared/components/grid/grid-secprofiles-org/grid-secprofiles-org.component';
import { OrgAdmin } from '../../../shared/models/org-admin.model';

@Component({
  selector: 'org-management-blade',
  templateUrl: './org-management-blade.component.html',
  styleUrls: ['./org-management-blade.component.css'],
  animations: [slideToRight()]
})
export class OrgManagementBladeComponent extends AgGridAbstractService implements OnInit, DoCheck, OnDestroy {
  level2: string;

  public isHoveredEditOrg = false;

  public usingService = 'orgServiceTable';

  // ag-Grid
  public rowData: any;
  public test: any;

  public headerHeight;
  public context;
  public frameworkComponents;
  public gridApi;
  public gridColumnApi;
  public cellRendererObject;

  public seeViewOrg = false;

  public response: any;
  refresh: boolean;
  admin: UserRequest;

  cellClicked: any;

  constructor(
    private org: Org,
    private viewstate: OrgViewStateService,
    private crumbstate: BreadcrumbService,

    // ag-Grid
    private orgservice: OrgsService<any>,
    private userservice: UserRequestService<UserRequest>,
    private secprofservice: SecProfService<SecurityProfileDto>,
    private orgVM: OrgViewModel,
    public globalEvent$: GlobalEvent$Service,
  ) {
    // ag-Grid
    super();
    this.columnDefs = [
      {
        headerName: 'Active',
        field: 'isActive',
        cellRenderer: "gridStatusRenderer",
        colId: "viewmore",
        suppressResize: true,
        suppressFilter: true,
        width: 55
      },
      { headerName: 'Organization', field: 'orgName', width: 200 },
      {
        headerName: 'Admins',
        field: 'adminIds',
        cellRenderer: "gridAdminsRenderer",
        colId: "admins",
        width: 100
      },
      {
        headerName: 'Security <br> Profiles',
        field: 'securityProfileIds',
        cellRenderer: "gridSecprofilesOrgRenderer",
        colId: "secprofiles",
        width: 100
      },
      { headerName: 'Domain', field: 'domain', cellStyle: { 'text-align': 'right' }, width: 100 },
      {
        headerName: 'View More',
        field: 'viewMore',
        cellRenderer: "viewMoreRenderer",
        colId: "params",
        suppressFilter: true,
        suppressResize: true,
        sortingOrder: [null],
        width: 75
      },
    ];
    this.context = { componentParent: this };
    this.frameworkComponents = {
      gridStatusRenderer: GridStatusRenderer,
      gridAdminsRenderer: GridAdminsRenderer,
      gridSecprofilesOrgRenderer: GridSecprofilesOrgRenderer,
      viewMoreRenderer: ViewMoreRenderer,
    };
    this.headerHeight = 45;
  }

  ngOnInit() {
    // ag-Grid THIS IS THE ONE LINER THAT BRINGS IN THE DATA
    this.rowData = this.orgservice.getListo();
    this.orgservice.getListo();

    this.viewstate.currentLevel2.subscribe(level2 => this.level2 = level2);
    this.crumbstate.changeLevel1(' > Organization Management');

    this.globalEvent$.currentGlobalEvent.subscribe(res => {
      this.refresh = res;
      console.log('this.refresh: ', this.refresh);
    });
  }

  onGridReady(params) {
    this.gridApi = params.api;
    this.gridColumnApi = params.columnApi;

    params.api.sizeColumnsToFit();
  }

  ngDoCheck() {
    if (this.agGrid !== undefined && this.refresh === true) {
      console.log("cells refreshed");
      console.log('this.refresh: ', this.refresh);
      this.refreshCells();
      this.refresh = false;
    }
  }

  refreshCells() {
    this.rowData = this.orgservice.getListo();
    this.agGrid.api.setRowData(this.rowData);
    // this.viewstate.changeLevel1(null);
    // this.viewstate.changeLevel1("orgBlade");
  }

  clearOrgVM() {
    // this.orgVM.reset();

    // this.org.id = "";
    // this.org.orgName = "";
    // this.org.active = false;
    // this.org.isMakerChecker = false;
    // this.org.addressLine1 = "";
    // this.org.addressLine2 = "";
    // this.org.state = "";
    // this.org.city = "";
    // this.org.postalCode = "";
    // this.org.country = "";
    // this.org.telephone = "";
    // this.org.ext = "";
    // this.org.domain = "";
    // this.org.adminIds = [];
    // this.org.userIds = [];
    // this.org.securityProfileIds = [];

    this.orgVM = null;

    console.log('this.orgVM: CLEARED', this.orgVM);
  }

  // this uses ag-Grid api to transfer data from the child cell renderer to this parent instance
  cellRendererMethodFromParent(cell) {
    this.cellRendererObject = cell;
    console.log('cellRendererObject: ', this.cellRendererObject);
  }

  mapClickToModel() {
    // this.orgVM = new OrgViewModel;
    console.log('this.getSelectedRows(): ', this.getSelectedRows());

    // grab the data available from the grid without making a call
    this.orgVM.orgInfo = this.getSelectedRows()[0];
    // if (this.getSelectedRows()[0]) {
    //   this.orgVM.orgInfo = this.getSelectedRows()[0];
    // } else {
      //   this.orgVM.reset();
      // }

    // add frontend meta data
    this.orgVM.orgInfo.new = false;
    this.orgVM.orgInfo.validity = true;
    // reset arrays
    const orgadmins = [];
    const secprofs = [];
    // these ids would have to be used to get and spread these profiles into the orgVM array
    this.getSelectedRows()[0].adminIds.map(x => {
      this.userservice.getObjecto(x).subscribe(y => { orgadmins.push(y); console.log('y', y); });
    });
    this.orgVM.orgAdmins = orgadmins;
    this.getSelectedRows()[0].securityProfileIds.map(x => {
      this.secprofservice.getObjecto(x).subscribe(y => { y.new = false; secprofs.push(y); console.log('y', y); });
    });
    this.orgVM.secProfiles = secprofs;

    // this.orgVM.orgAdmins = this.getSelectedRows()[0].adminIds;
    // this.orgVM.secProfiles = this.getSelectedRows()[0].securityProfileIds;

    console.log('this.orgVM.orgInfo: ', this.orgVM.orgInfo);
    console.log('this.orgVM.orgAdmins: ', this.orgVM.orgAdmins);
    console.log('this.orgVM.customers: ', this.orgVM.customers);
    console.log('this.orgVM.secProfiles: ', this.orgVM.secProfiles);
    console.log('this.orgVM click finished: ', this.orgVM);
  }

  ngOnDestroy() {
    this.crumbstate.changeLevel1(null);
  }

  newLevel2(state) {
    this.viewstate.changeLevel2(state);
  }

  isSelectedNewLevel2() {
    if (this.orgVM.orgInfo.id) {
      this.viewstate.changeLevel2('orgEdit');
    }
  }


  newLevel3(state) {
    this.viewstate.changeLevel3(state);
  }
}

第一个窗口显示清除数据的三次尝试第二个窗口显示事件发生的位置第三个窗口,回到组件中,显示数据成功放入单例的位置(但后来我无法清除它因此出现问题) 在此处输入图像描述

标签: angulartypescriptsingletonangular-services

解决方案


我必须 reset() 然后将引用设置回主对象。

此方法在您的对象中留下了额外的属性,我试图删除这些属性以免混淆,但这会导致问题,我确信这是因为它认为我试图删除来自构造函数的属性。

...我敢肯定有一个更好的模式来保持单身。如果你有魔法,请告诉我。

在此处输入图像描述 在此处输入图像描述


推荐阅读