Typescript - невозможно обновить объект внутри объекта - PullRequest
0 голосов
/ 12 июля 2020

У меня есть следующий объект Typescript:

export class DocumentIndex {
  objectId: number;
  key = '';
  iconPath = '';
  searchParm: SearchParm = new SearchParm();

  constructor(public name: string, public description: string) {
    this.objectId = JsUtil.getObjectId();
  }
}

Моя цель - изменить значения объекта SearchParm. Объект SearchParm определяется следующим образом:

export class SearchParm {
  searchType = SearchType.none;
  searchTerm = '';
  constructor() {
  }
}

Вот код, в котором я пытаюсь установить для searchTerm и searchType другое значение:

let docIndex = new DocumentIndex(searchValue, '');

docIndex.searchParm.searchTerm = searchValue; // searchValue is a string set to "G Triad"
docIndex.searchParm.searchType = SearchType.fullText; // this is a string set to "fullText"

console.log('documentIndex searchParm...', docIndex.searchParm);
console.log('documentIndex...', docIndex);

Вот результат в Chrome. Обратите внимание, что SearchParm остается неизменным по сравнению с исходным значением.

Chrome результат

Что здесь могло происходить? Тот же код использовался в другом месте, над чем я работаю, и работает правильно.

1 Ответ

0 голосов
/ 12 июля 2020

Когда вы console.log(obj) для некоторого объекта obj, вы можете подумать, что он будет записывать в консоль какую-то информацию о состоянии obj, когда вы его регистрировали. Это не гарантируется. Часто браузеры сохраняют ссылку на obj, и всякий раз, когда вы смотрите на консоль, вы увидите текущее состояние obj. Поэтому, если вы измените obj после регистрации, вы можете быть сбиты с толку:

const obj = {foo: "bar"}; // empty
console.log(obj); // what gets logged here?  {foo: "bar"} or {foo: "baz"}?
obj.foo = "baz";

Для этого кода Firefox показывает мне следующее свернутое / расширенное представление:

// collapsed view
// ▶ Object { foo: "bar" }

// expanded view
// ▼ {…}
//   foo: "baz"

Таким образом, вы не можете действительно полагаться на то, что console.log() делает со ссылками на объекты. Вместо этого вы можете подумать о том, чтобы выполнял что-то вроде JSON.stringify(obj), прежде чем регистрировать его . Это даст преимущество захвата по крайней мере части состояния зарегистрированного объекта во время регистрации:

const obj = {foo: "bar"}; // empty
console.log(JSON.stringify(obj)); // definitely logs {"foo":"bar"}
obj.foo = "baz";

В вашем случае, я сильно подозреваю, что вы переназначаете docIndex.searchParm после кода регистрации. Это может легко привести к тому, что console.log(docIndex) покажет текущее значение его свойства searchParm, а console.log(docIndex.searchParm) покажет текущее значение объекта, которое раньше было его свойством searchParm:

docIndex.searchParm.searchTerm = searchValue; // searchValue is a string set to "G Triad"
docIndex.searchParm.searchType = SearchType.fullText; // this is a string set to "fullText"

console.log('documentIndex searchParm...', docIndex.searchParm);
console.log('documentIndex...', docIndex);

// this happens later 
docIndex.searchParm = new SearchParm();

// documentIndex searchParm... Object { searchType: "fullText", searchTerm: "G Triad" }
// documentIndex... searchParm:  ▼ {…} 
//                                   Object { searchType: "none", searchTerm: "" }

Проблема должна исчезнуть, если вы используете console.log(JSON.stringify()):

console.log('documentIndex searchParm...', JSON.stringify(docIndex.searchParm));
// documentIndex searchParm... documentIndex searchParm... {"searchType":"fullText","searchTerm":"G Triad"}

console.log('documentIndex...', JSON.stringify(docIndex));
// documentIndex... searchParm:  {"name":"G Triad","description":"","key":"",
//  "iconPath": "", "searchParm": { "searchType": "fullText", "searchTerm": "G Triad" }, 
//  "objectId": 123}

Хорошо, надеюсь, что это поможет; удачи!

Детская площадка ссылка на код

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...