Не удалось сбросить мои службы Singleton, предоставленные inRoot

Я сделал одноэлементный сервис, который обновляет данные от представления к представлению. Поэтому я использую их как DTO в представлении. Этот основной одноэлементный сервис ссылается на другие одноэлементные сервисы. В основной службе у меня есть функция reset(), которая должна возвращать свойства основной службы к их исходным значениям и ссылаться на методы reset() периферийной одноэлементной службы. К сожалению, вместо того, чтобы выполнять более позднюю часть, он перезаписывает ссылки основного одноэлементного сервиса на периферийные одноэлементные сервисы новым свойством (названным так же, как ссылка, помещенная в конструктор основного сервиса), но каким-то образом должен по-прежнему получать доступ к этому периферийному сервису метод, чтобы он знал, для чего установить это новое свойство.

Почему он не распознает организацию в конструкторе организации??? введите здесь описание изображения

Почему этот метод сброса не работает? Есть ли лучший способ/лучшая практика для этого? Спасибо.

Ниже я предоставил основной синглтон вместе с синглтонами, на которые есть ссылки внутри.

Пожалуйста, дайте мне знать, если мне нужно уточнить.

Главный синглтон

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

Первое окно показывает три попытки очистки данных Второе окно показывает, где происходит событие Третье окно, обратно в компонент, показывает, где данные успешно помещаются в синглтон (но тогда я не могу очистить его, отсюда и проблема) enter


person imnickvaughn    schedule 27.10.2018    source источник
comment
Проблема только в том, что значения не сбрасываются? Ваши console.log печатаются?   -  person user184994    schedule 27.10.2018
comment
Да, я могу нормально загружать в них другие значения, но когда дело доходит до использования этой функции сброса, она не работает. Журналы консоли согласуются с тем, что я вижу в представлении (данные не сбрасываются), поэтому я не думаю, что я где-то отключил соединение с синглтоном.   -  person imnickvaughn    schedule 27.10.2018
comment
Итак, вы не видите журналы, напечатанные на консоли? Не могли бы вы показать код, где вас зовут reset в основном синглтоне?   -  person user184994    schedule 27.10.2018
comment
Добавлен. Я вижу изменение информации в консоли, я тоже добавлю изображение   -  person imnickvaughn    schedule 27.10.2018
comment
Строка, где вы вызываете this.orgVM.reset(), закомментирована?   -  person user184994    schedule 27.10.2018
comment
Наверное не очень понятно... Первое окно показывает три попытки очистки данных   -  person imnickvaughn    schedule 27.10.2018
comment
Я выложил финальную картинку о том, что происходит. По какой-то причине он создает новое свойство с именем org в классе OrgViewModel вместо использования org в конструкторе и доступа к его reset(). Вы знаете, почему он это делает? Если вы это сделаете, вы можете поместить это в ответ, чтобы я мог закрыть его и поблагодарить вас.   -  person imnickvaughn    schedule 27.10.2018


Ответы (1)


Мне пришлось reset() И ЗАТЕМ установить ссылку обратно на основной объект.

Этот метод оставляет дополнительные свойства в вашем объекте, которые я пытался удалить, чтобы не путать, но это вызвало проблему, которая, я уверен, возникла из-за того, что он думал, что я пытаюсь удалить свойства, поступающие из конструктора.

... Я уверен, что есть лучший шаблон для хранения синглтона. Пожалуйста, дайте мне знать, если у вас есть magiks.

введите здесь описание изображения введите здесь описание изображения

person imnickvaughn    schedule 27.10.2018