itsource

각도 2: 배열의 변화를 감지하는 방법?(@입력 속성)

mycopycode 2023. 10. 14. 10:07
반응형

각도 2: 배열의 변화를 감지하는 방법?(@입력 속성)

ajax 요청을 사용하여 개체 배열을 검색하는 상위 구성 요소가 있습니다.

이 구성 요소에는 두 개의 자식 구성 요소가 있습니다.그 중 하나는 트리 구조의 객체를 보여주고 다른 하나는 테이블 형식으로 내용을 렌더링합니다.부모는 @입력 속성을 통해 배열을 자녀에게 전달하고 자녀는 내용을 올바르게 표시합니다.역시 다.

개체 내의 일부 필드를 변경할 때 문제가 발생합니다. 하위 구성 요소는 이러한 변경 사항을 알리지 않습니다.배열을 해당 변수에 수동으로 재할당하는 경우에만 변경 사항이 트리거됩니다.

나는 녹아웃 JS와 일하는 것에 익숙하고 관찰 가능한 어레이와 비슷한 효과를 얻어야 합니다.

DoCheck에 대한 내용을 읽었는데 어떻게 작동하는지 잘 모르겠습니다.

OnChanges Lifecycle Hook은 입력 속성의 인스턴스가 변경될 때만 트리거합니다.

입력 배열 내부의 요소가 추가, 이동 또는 제거되었는지 확인하려면 ItableDifferences(ItableDifferences)를 사용합니다.DoCheck라이프사이클 후크는 다음과 같습니다.

constructor(private iterableDiffers: IterableDiffers) {
    this.iterableDiffer = iterableDiffers.find([]).create(null);
}

ngDoCheck() {
    let changes = this.iterableDiffer.diff(this.inputArray);
    if (changes) {
        console.log('Changes detected!');
    }
}

배열 내부의 객체 변화를 탐지해야 하는 경우 모든 요소를 반복하고 각 요소에 대해 KeyValueDiffer를 적용해야 합니다(이전 확인과 병행하여 수행할 수 있음).

자세한 내용은 이 게시물을 참조하십시오.Angular2에서 배열 내부의 객체 변화 감지

배열을 빈 배열과 병합하여 항상 배열에 대한 새 참조를 만들 수 있습니다.

this.yourArray = [{...}, {...}, {...}];
this.yourArray[0].yourModifiedField = "whatever";

this.yourArray = [].concat(this.yourArray);

위의 코드는 배열 참조를 변경하고 자식 구성 요소에서 OnChanges 메커니즘을 트리거합니다.

다음 기사를 읽으십시오. 가변 대 불변 객체를 놓치지 마십시오.

핵심 문제는 배열 참조는 그대로 유지하면서 배열 요소를 변형한다는 것입니다.그리고 Angular2 변경 감지는 변경을 감지하기 위해 배열 참조만 확인합니다.불변의 대상에 대한 개념을 이해하고 나면 왜 문제가 있는지, 어떻게 해결해야 하는지 이해할 수 있을 것입니다.

저는 이런 문제를 피하기 위해 프로젝트 중 하나에 리덕스 스토어를 사용합니다.

https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html

사용할 수 있는 방법

*ngFor에서 사용합니다.

constructor(private _differs: IterableDiffers) {}

ngOnChanges(changes: SimpleChanges): void {
  if (!this._differ && value) {
     this._differ = this._differs.find(value).create(this.ngForTrackBy);
  }
}

ngDoCheck(): void {
  if (this._differ) {
    const changes = this._differ.diff(this.ngForOf);
    if (changes) this._applyChanges(changes);
  }
}

내가 할 수 있는 일입니다.

@Component({
  selector: 'my-component',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.scss']
})
export class MyComponent implements DoCheck {

  @Input() changeArray: MyClassArray[]= [];
  private differ: IterableDiffers;

  constructor(private differs: IterableDiffers) {
    this.differ = differs;
  }

  ngDoCheck() {
    const changes = this.differ.find(this.insertedTasks);
    if (changes) {
      this.myMethodAfterChange();
  }
}

이미 응답한 것으로 보입니다.하지만 미래의 문제를 찾는 사람들을 위해, 저는 제가 가진 변화 감지 문제를 조사하고 디버깅할 때 놓친 것을 추가하고 싶었습니다.이제, 제 문제는 좀 고립되어 있었고, 물론 제 쪽에서 바보 같은 실수를 저질렀지만, 그럼에도 불구하고 관련이 있습니다.할 때Array아니면Object참고로 정확한 범위에 있는지 확인합니다.다를 .setInterval(myService.function, 1000)서,myService.function()서비스 외부에서 사용한 퍼블릭 어레이의 값을 업데이트할 것입니다. 있었기다이어야 올바른 사용법은 다음과 같습니다.setInterval(myService.function.bind(this), 1000)는 변경 을 시도하느라 을 낭비했습니다.때 말이죠 저는 변경 탐지 해킹을 시도하는 데 시간을 낭비했는데, 이는 어리석은 실수였습니다.변경 탐지 솔루션을 시도하기 전에 문제의 범위를 제거하면 시간을 절약할 수 있습니다.

concat 방법을 통해 변경 감지를 트리거하는 대신 ES6 destructuring operator를 사용하는 것이 더 우아할 수 있습니다.

this.yourArray[0].yourModifiedField = "whatever";
this.yourArray = [...this.yourArray];

구성요소 템플릿에서 배열을 직접 사용하는 경우 불순물 파이프를 사용할 수 있습니다.(이 예는 심층적인 검사가 필요 없는 단순한 어레이를 위한 것입니다.)

@Pipe({
  name: 'arrayChangeDetector',
  pure: false
})
export class ArrayChangeDetectorPipe implements PipeTransform {
  private differ: IterableDiffer<any>;

  constructor(iDiff: IterableDiffers) {
    this.differ = iDiff.find([]).create();
  }

  transform(value: any[]): any[] {
    if (this.differ.diff(value)) {
      return [...value];
    }
    return value;
  }
}
<cmp [items]="arrayInput | arrayChangeDetector"></cmp>

여전히 어레이 문제를 겪고 있는 시간 여행자들을 위해 여기서는 몇 가지 가능한 해결책과 함께 문제를 재현합니다.

https://stackblitz.com/edit/array-value-changes-not-detected-ang-8

솔루션은 다음과 같습니다.

  • NgDo체크
  • 파이프 사용
  • 불변 JS NPM github 사용

언급URL : https://stackoverflow.com/questions/42962394/angular-2-how-to-detect-changes-in-an-array-input-property

반응형