web-dev-qa-db-ja.com

Angular 7:サービスインスタンスが正しく動作していません

私のアプリには、「フィルター」と「ホーム」という2つのコンポーネントがあります。これら2つのコンポーネントは、アプリコンポーネントの子コンポーネントです。

サービスを介してフィルターコンポーネントからホームコンポーネントに渡したいタイプの以下のオブジェクトがあります。また、フィルターコンポーネントで変更されるたびにこのデータをホームコンポーネントで更新するため、BehaviorSubjectをサービスで使用します。

モデル:filter-response.model.ts

export interface FilterResponse{
    filter:string;
    filterlist:string[];
}

filter.component.ts

export class FilterComponent implements OnInit {
    filterMainList:FilterResponse[]=[
        {
            "filter": "abc",
            "filterlist": ["a","b","c"]
        },
        {
            "filter": "def",
            "filterlist":["d","e","f"]
        },
        {
            "filter": "ghi",
            "filterlist": ["g","h","i"]
        }
    ];
    constructor(private filterService:FilterService,) {
        this.filterService.setFilterConditions(this.filterMainList);
    }
    ngOnInit() {
    }
}

ホームコンポーネントでデータを受信しましたが、データに変更を加えたいと考えています。

home.component.ts

export class HomeComponent implements OnInit {
  constructor(private filterService:FilterService) {
    this.filterService.getFilterConditions().subscribe((data)=>{
      let tc:FilterResponse[]=data
      for(let f in tc){
        tc[f].filterlist=['changes'];//this is where I make the changes
      }
    });
   }
  ngOnInit() {
  }
}

振る舞い主体のフィルターサービスを持っています。これは私が混乱したところです。 next()の前にサービスのデータをここに記録します。実際にここに表示されるデータは、ホームコンポーネントで変更したものです。つまり、ホームコンポーネントのデータのインスタンスで行った変更も、インスタンスのインスタンスに影響(変更)しています。稼働中のデータ。

filter.service.ts

@Injectable({
    providedIn:'root'
})
export class FilterService{
    private filterConditions = new BehaviorSubject<FilterResponse[]>(null);
    constructor(){}
    setFilterConditions(filterList:FilterResponse[]){
        console.log(filterList);//data changes incorrectly
        this.filterConditions.next(filterList);
    }
    getFilterConditions():Observable<FilterResponse[]>{
        return this.filterConditions.asObservable();        
    }
}

私のコンソールログ:

console log

実際にフィルターコンポーネントに渡したデータであるはずのデータ。しかし、ホームコンポーネントで変更したデータが表示されます。

そして最後にapp.component.ts、それが役立つ場合

app.component.ts

<app-filter></app-filter>
<app-home></app-home>

もう1つ、お知らせしたいことがあります。 Stackblitzでシナリオを再現してみました。しかし、ひねりはそれがそこでうまく機能していることです。

https://stackblitz.com/edit/angular-ivy-9th5pj

私のプロジェクトで欠けているものを親切に説明してください。または、これはサービスが角度で機能する実際の方法ですか?.

4
Dev Anand

私はクッシュの答えを拡張します。したがって、ディープコピーを作成しても何も機能しない場合は、loadashからcloneDeep関数を使用できます。このオプションは最悪の場合に使用してください(修正プログラムの問題)。この問題は、浅いコピーが原因で発生します。したがって、それぞれの場合に配列を返すときは、新しい配列ではなく配列のアドレスを返します。したがって、配列に変更が発生すると、元の配列に変更が発生します。そして、JSON.stringigyまたはdeepClone関数を使用すると、内部的に異なるアドレスで配列のコピーを作成します

setFilterConditions(filterList:FilterResponse[]){
    this.filterConditions.next(cloneDeep(filterList));
}
0
pbmahadik