Angular 这是阵列内存泄漏吗?
正如您在所附图片中看到的,我正在调试以找出我的应用程序中的内存泄漏。Angular 这是阵列内存泄漏吗?,angular,debugging,memory-leaks,google-chrome-devtools,Angular,Debugging,Memory Leaks,Google Chrome Devtools,正如您在所附图片中看到的,我正在调试以找出我的应用程序中的内存泄漏。 在“数组”项下有一个非常高的增量!“系统”,通过在主页(没有内容的地方)和图库之间切换20次,内存堆从6MB变为11MB。 ngrx调度和选择器用于库中,我使用异步管道将数据传递给库组件。我说的是gallery组件,因为通过排除它,对它进行评论,内存泄漏不再存在 首先,我想知道这是否真的是内存泄漏,如果是,我想知道如何消除它。既然这些是数组,那么它们不应该在组件销毁时被释放吗?那么“系统”三角洲呢?谢谢 上下文组件 @Com
在“数组”项下有一个非常高的增量!“系统”,通过在主页(没有内容的地方)和图库之间切换20次,内存堆从6MB变为11MB。
ngrx调度和选择器用于库中,我使用异步管道将数据传递给库组件。我说的是gallery组件,因为通过排除它,对它进行评论,内存泄漏不再存在 首先,我想知道这是否真的是内存泄漏,如果是,我想知道如何消除它。既然这些是数组,那么它们不应该在组件销毁时被释放吗?那么“系统”三角洲呢?谢谢 上下文组件
@Component({
selector: 'app-conteiner-gallery',
template:`
<app-gallery [allCars]="allCars$ | async"
[brands]="brands$ | async"
[types]="types$ | async"
[usersRatings]="usersRatings$ | async"
[recentSeenCars]="recentSeenCars$ | async"
[observedCars]="observedCars$ | async"
(setObservedCarAction)="onSetObservedCar($event)"
(setNotObservedCarAction)="onSetNotObservedCar($event)"
(setObservedCarsAction)="onSetObservedCars($event)"
(setBrandChecked)="onSetBrandChecked($event)"
(setBrandsChecked)="onSetBrandsChecked($event)"
(setTypeChecked)="onSetTypeChecked($event)"
(setTypesChecked)="onSetTypesChecked($event)">
</app-gallery>
`
})
export class ConteinerGalleryComponent implements OnInit, OnDestroy{
allCars$:Observable<Car[]>
brands$:Observable<BrandCB[]>
types$:Observable<TypeCB[]>
usersRatings$:Observable<UserRating[]>
recentSeenCars$:Observable<RecentSeenCar[]>
observedCars$:Observable<ObservedCar[]>
unsubscription$:Subject<boolean> = new Subject
isStoreLoaded:boolean = false
isStoreRecentSeenCarsLoaded:boolean = false
constructor( private store:Store<StoreState>, private authService:AuthenticationService){}
ngOnDestroy():void{
this.unsubscription$.next(true)
this.unsubscription$.complete()
}
ngOnInit(): void {
this.store.pipe(select(statusSelectors.isStoreLoaded))
.pipe( takeUntil(this.unsubscription$))
.subscribe( loaded => this.isStoreLoaded = loaded)
this.store.pipe(select(statusSelectors.isRecentSeenCarsLoaded))
.pipe(takeUntil(this.unsubscription$))
.subscribe( loaded => this.isStoreRecentSeenCarsLoaded = loaded)
!this.isStoreLoaded ? this.store.dispatch(carsActions.getAllCars()) : null
!this.isStoreLoaded ? this.store.dispatch(brandsActions.getBrands()) : null
!this.isStoreLoaded ? this.store.dispatch(typesActions.getTypes()) : null
!this.isStoreLoaded ? this.store.dispatch(userRatingsActions.getUsersRatings()) : null
if(!this.isStoreRecentSeenCarsLoaded && this.authService.currentUserValue){
this.store.dispatch(recentSeenCarsActions.getRecentSeenCars())
this.store.dispatch(statusActions.setRecentSeenCarsLoaded({loaded:true}))
}
if(!this.isStoreLoaded)
this.authService.currentUserValue ? this.store.dispatch(observedCarsActions.getObservedCars()) : null
this.store.dispatch(statusActions.setStoreLoaded({loaded:true}))
this.allCars$ = this.store.pipe(select(carsSelectors.getAllCars))
this.brands$ = this.store.pipe(select(brandsSelectors.getBrands))
this.types$ = this.store.pipe(select(typeSelectors.getTypes))
this.usersRatings$ = this.store.pipe(select(userRatingsSelectors.getUsersRatings))
this.recentSeenCars$ = this.store.pipe(select(userRecentSeenCarsSelectors.getUsers))
this.observedCars$ = this.store.pipe(select(userObservedCarsSelectors.getUsers))
}
onSetObservedCar(carId:number):void{
let observed:ObservedCar = {id:null, carId:carId, userId:null}
this.store.dispatch(observedCarsActions.setObservedCar({carId}))
}
onSetNotObservedCar(carId:number):void{
this.store.dispatch(observedCarsActions.setNotObservedCar({carId}))
}
onSetObservedCars(cars:Car[]):void{
this.store.dispatch(carsActions.setCarsWithObserved({cars}))
}
onSetBrandChecked(brand:BrandCB):void{
this.store.dispatch(brandsActions.setBrandChecked({brand}))
}
onSetBrandsChecked(brands:BrandCB[]):void{
this.store.dispatch(brandsActions.setBrandsChecked({brands}))
}
onSetTypeChecked(typee:TypeCB):void{
this.store.dispatch(typesActions.setTypeChecked({typee}))
}
onSetTypesChecked(types:TypeCB[]):void{
this.store.dispatch(typesActions.setTypesChecked({types}))
}
public logout():void{
this.store.dispatch(statusActions.setRecentSeenCarsLoaded({loaded:false}))
}
}
export class GalleryComponent implements OnInit, DoCheck, OnChanges{
@Input() allCars:Car[]
@Input() brands:BrandCB[]
@Input() types:TypeCB[]
@Input() usersRatings:UserRating[]
@Input() recentSeenCars:Car[]
@Input() observedCars:ObservedCar[]
@Output() setObservedCarAction = new EventEmitter<any>()
@Output() setNotObservedCarAction = new EventEmitter<any>()
@Output() setObservedCarsAction = new EventEmitter<any>()
@Output() setBrandCount = new EventEmitter<any>()
@Output() setTypeCount = new EventEmitter<any>()
@Output() setBrandChecked = new EventEmitter<any>()
@Output() setTypeChecked = new EventEmitter<any>()
@Output() setBrandsChecked = new EventEmitter<any>()
@Output() setTypesChecked = new EventEmitter<any>()
filteredCars:Car[] = []
/* brandsCB:BrandCB[] = []
typesCB:TypeCB[] = [] */
user:User
iterableDiffer:IterableDiffer<any>
checkboxBrandAll:boolean = true
checkboxTypeAll:boolean = true
leftConteinerClass:string
faBars = faBars
constructor( private authService:AuthenticationService, private iterableDiffers: IterableDiffers){
this.iterableDiffer = iterableDiffers.find([]).create(null);
}
// evocata quando ci sono cambiamenti nelle proprietà di input
ngOnChanges(changes: SimpleChanges): void {
// c'è bisogno di chiamare filterCars perchè oltre a filtrare le auto aggiorna l'array in visualizzazione
changes.allCars ? this.filterCars(this.brands, this.types) : null
}
ngDoCheck(): void {
// used when observed buttons are pressed
let changes = this.iterableDiffer.diff(this.observedCars);
if (changes) {
this.user ? this.setObservedCars() : null
}
}
ngOnInit():void{
this.user = this.authService.currentUserValue
this.user ? this.setObservedCars() : null
this.initFilters()
this.filterCars(this.brands, this.types)
this.showNormalLeftConteiner()
window.addEventListener('resize', () => this.showNormalLeftConteiner())
}
// setta le checkbox degli "all" dei filtri a false se altre checkbox risultano selezionate
initFilters(){
let filtersBrands:boolean = false
let filtersTypes:boolean = false
this.brands.some( brand => brand.checked) ? filtersBrands = true : null
this.types.some( type => type.checked) ? filtersTypes = true : null
filtersBrands ? this.checkboxBrandAll = false : null
filtersTypes ? this.checkboxTypeAll = false : null
}
// operazioni da effettuara al cambiamento di una checkbox dei filtri.
checkboxChange(event, brand, type):void{
let name = event.target.name;
let checked = event.target.checked;
let brands:BrandCB[] = JSON.parse(JSON.stringify(this.brands))
let types:TypeCB[] = JSON.parse(JSON.stringify(this.types))
//BRANDS
if(name =='allBrands'){
if(checked == true){
brands.map(brand => brand.checked = false);
this.checkboxBrandAll = true
this.filterCars(brands, types)
brands = this.countBrands(brands)
types = this.countTypes(types)
this.setBrandsChecked.emit(brands)
this.setTypesChecked.emit(types)
}else{
this.checkboxBrandAll = true
}
} else if(name == 'otherBrands'){
brands = brands.map( b => {
if(b.id == brand.id){
return ({...brand, checked:checked})
}else{
return b
}
})
if(checked == true){
this.checkboxBrandAll = false;
}else
brands.some( b => b.checked) ? null : this.checkboxBrandAll = true
this.filterCars(brands, types)
brands = this.countBrands(brands)
types = this.countTypes(types)
this.setBrandsChecked.emit(brands)
this.setTypesChecked.emit(types)
}
// TYPES
if(name =='allTypes'){
if(checked == true){
types.map(type => type.checked = false)
this.checkboxTypeAll = true
this.filterCars(brands, types)
brands = this.countBrands(brands)
types = this.countTypes(types)
this.setBrandsChecked.emit(brands)
this.setTypesChecked.emit(types)
}else{
this.checkboxTypeAll = true
}
} else if(name == 'otherTypes'){
types = types.map( t => {
if(t.id == type.id){
return ({...type, checked:checked})
}else{
return t
}
})
if(checked == true){
this.checkboxTypeAll = false;
}else
types.some( t => t.checked) ? null : this.checkboxTypeAll = true
this.filterCars(brands, types)
brands = this.countBrands(brands)
types = this.countTypes(types)
this.setBrandsChecked.emit(brands)
this.setTypesChecked.emit(types)
}
}
// aggiorna la proprietà "observed" di allCars
setObservedCars():void{
let allCars:Car[] = JSON.parse(JSON.stringify(this.allCars))
let observedCars:ObservedCar[] = [...this.observedCars]
allCars.map( car => {
// se la car è osservata, setta "observed" a true
observedCars.some( obs => obs.carId == car.id) ? car.observed = true : car.observed = false
})
this.setObservedCarsAction.emit(allCars)
}
// aggiorna l array per la gallery (this.filteredCars) con l'array modificato eventualmente nei filtri o nella proprietà observed (this.allCars)
filterCars(brands:BrandCB[], types:TypeCB[]):void{
let allCars = [...this.allCars];
const checkedBrands = brands.filter(brand => brand.checked);
const checkedTypes = types.filter(type => type.checked);
let filteredCars:Car[];
if(!this.checkboxBrandAll && !this.checkboxTypeAll){
filteredCars = allCars.filter(car => checkedBrands.find(brand => brand.name === car.brand) && checkedTypes.find(type => type.name === car.type));
} else if(!this.checkboxBrandAll && this.checkboxTypeAll){
filteredCars = allCars.filter(car => checkedBrands.find(brand => brand.name === car.brand));
}else if(this.checkboxBrandAll && !this.checkboxTypeAll){
filteredCars = allCars.filter(car => checkedTypes.find(type => type.name ===car.type));
}else{
filteredCars = [...allCars];
}
this.filteredCars = [...filteredCars]
}
// conta le occorrenze di ogni brand, ad esempio ferrari(2)
countBrands(brands:BrandCB[]):BrandCB[]{
let br:BrandCB[] = brands.map( brand => {
let count = 0;
this.filteredCars.forEach( car => {
brand.name == car.brand ? count++ : null
})
brand.count = count;
return brand
})
return br
}
// conta le occorrenze di ogni type, ad esempio jeep(2)
countTypes(types:TypeCB[]):TypeCB[]{
let ty:TypeCB[] = types.map( type => {
let count = 0;
this.filteredCars.forEach( car => {
type.name == car.type ? count++ : null
})
type.count = count;
return type
})
return ty
}
showMobileLeftConteiner():void{
this.leftConteinerClass = 'show-mobile-left-conteiner'
}
showNormalLeftConteiner():void{
if(window.innerWidth >= 1051){
this.leftConteinerClass = 'show-normal-left-conteiner'
}else{
this.hideLeftContenier()
}
}
hideLeftContenier():void{
this.leftConteinerClass = 'hide-left-conteiner'
}
onSetObservedCar(carId:number):void{
this.setObservedCarAction.emit(carId)
}
onSetNotObservedCar(carId:number):void{
this.setNotObservedCarAction.emit(carId)
}
}
@组件({
选择器:“应用程序上下文库”,
模板:`
`
})
导出类ConteinerGalleryComponent实现OnInit、OnDestroy{
allCars$:可观察
品牌美元:可观察
类型$:可观察
usersRatings$:可观察
近期SEENCARS$:可观测
观测车辆$:可观测
退订$:科目=新科目
isStoreLoaded:boolean=false
isStoreRecentSeenCarsLoaded:boolean=false
构造函数(私有存储:存储,私有authService:AuthenticationService){}
ngOnDestroy():void{
此.unsubscription$.next(true)
此.unsubscription$.complete()
}
ngOnInit():void{
this.store.pipe(选择(statusSelectors.isStoreLoaded))
.pipe(takeUntil(此.unsubscription$))
.subscribe(已加载=>this.isStoreLoaded=已加载)
this.store.pipe(选择(statusSelectors.isRecentSeenCarsLoaded))
.pipe(takeUntil(此.unsubscription$))
.subscribe(已加载=>this.isStoreRecentSeenCarsLoaded=已加载)
!this.isStoreLoaded?this.store.dispatch(carsActions.getAllCars()):null
!this.isStoreLoaded?this.store.dispatch(brandsActions.getBrands()):null
!this.isStoreLoaded?this.store.dispatch(typesActions.getTypes()):null
!this.isStoreLoaded?this.store.dispatch(userRatingsActions.getUsersRatings()):null
如果(!this.isStoreRecentSeenCarsLoaded&&this.authService.currentUserValue){
this.store.dispatch(recentSeencarActions.getRecentSeenCars())
this.store.dispatch(statusActions.setRecentSeenCarsLoaded({loaded:true}))
}
如果(!this.isStoreLoaded)
this.authService.currentUserValue?this.store.dispatch(observedCarsActions.getObservedCars()):null
this.store.dispatch(statusActions.setStoreLoaded({loaded:true}))
this.allCars$=this.store.pipe(选择(carsselector.getAllCars))
this.brands$=this.store.pipe(选择(brandsSelectors.getBrands))
this.types$=this.store.pipe(select(typeSelectors.getTypes))
this.usersRatings$=this.store.pipe(选择(userratingsselector.getUsersRatings))
this.recentSeenCars$=this.store.pipe(选择(userRecentSeenCarsSelectors.getUsers))
this.observedCars$=this.store.pipe(选择(userObservedCarsSelectors.getUsers))
}
onSetObservedCar(carId:编号):无效{
let ObservedCar={id:null,carId:carId,userId:null}
this.store.dispatch(observedCarsActions.setObservedCar({carId}))
}
onSetNotObservedCar(carId:编号):无效{
this.store.dispatch(observedCarsActions.setNotObservedCar({carId}))
}
onSetObservedCars(cars:Car[]):无效{
this.store.dispatch(carsActions.setCarsWithObserved({cars}))
}
onSetBrandChecked(品牌:BrandCB):无效{
this.store.dispatch(brandsActions.setBrandChecked({brand}))
}
onSetBrandsChecked(品牌:BrandCB[]):无效{
this.store.dispatch(brandsActions.setBrandsChecked({brands}))
}
onSetTypeChecked(类型E:TypeCB):无效{
this.store.dispatch(typesActions.setTypeChecked({typee}))
}
onSetTypesChecked(类型:TypeCB[]):void{
this.store.dispatch(typesActions.setTypesChecked({types}))
}
公共注销():无效{
this.store.dispatch(statusActions.setRecentSeenCarsLoaded({loaded:false}))
}
}
库组件
@Component({
selector: 'app-conteiner-gallery',
template:`
<app-gallery [allCars]="allCars$ | async"
[brands]="brands$ | async"
[types]="types$ | async"
[usersRatings]="usersRatings$ | async"
[recentSeenCars]="recentSeenCars$ | async"
[observedCars]="observedCars$ | async"
(setObservedCarAction)="onSetObservedCar($event)"
(setNotObservedCarAction)="onSetNotObservedCar($event)"
(setObservedCarsAction)="onSetObservedCars($event)"
(setBrandChecked)="onSetBrandChecked($event)"
(setBrandsChecked)="onSetBrandsChecked($event)"
(setTypeChecked)="onSetTypeChecked($event)"
(setTypesChecked)="onSetTypesChecked($event)">
</app-gallery>
`
})
export class ConteinerGalleryComponent implements OnInit, OnDestroy{
allCars$:Observable<Car[]>
brands$:Observable<BrandCB[]>
types$:Observable<TypeCB[]>
usersRatings$:Observable<UserRating[]>
recentSeenCars$:Observable<RecentSeenCar[]>
observedCars$:Observable<ObservedCar[]>
unsubscription$:Subject<boolean> = new Subject
isStoreLoaded:boolean = false
isStoreRecentSeenCarsLoaded:boolean = false
constructor( private store:Store<StoreState>, private authService:AuthenticationService){}
ngOnDestroy():void{
this.unsubscription$.next(true)
this.unsubscription$.complete()
}
ngOnInit(): void {
this.store.pipe(select(statusSelectors.isStoreLoaded))
.pipe( takeUntil(this.unsubscription$))
.subscribe( loaded => this.isStoreLoaded = loaded)
this.store.pipe(select(statusSelectors.isRecentSeenCarsLoaded))
.pipe(takeUntil(this.unsubscription$))
.subscribe( loaded => this.isStoreRecentSeenCarsLoaded = loaded)
!this.isStoreLoaded ? this.store.dispatch(carsActions.getAllCars()) : null
!this.isStoreLoaded ? this.store.dispatch(brandsActions.getBrands()) : null
!this.isStoreLoaded ? this.store.dispatch(typesActions.getTypes()) : null
!this.isStoreLoaded ? this.store.dispatch(userRatingsActions.getUsersRatings()) : null
if(!this.isStoreRecentSeenCarsLoaded && this.authService.currentUserValue){
this.store.dispatch(recentSeenCarsActions.getRecentSeenCars())
this.store.dispatch(statusActions.setRecentSeenCarsLoaded({loaded:true}))
}
if(!this.isStoreLoaded)
this.authService.currentUserValue ? this.store.dispatch(observedCarsActions.getObservedCars()) : null
this.store.dispatch(statusActions.setStoreLoaded({loaded:true}))
this.allCars$ = this.store.pipe(select(carsSelectors.getAllCars))
this.brands$ = this.store.pipe(select(brandsSelectors.getBrands))
this.types$ = this.store.pipe(select(typeSelectors.getTypes))
this.usersRatings$ = this.store.pipe(select(userRatingsSelectors.getUsersRatings))
this.recentSeenCars$ = this.store.pipe(select(userRecentSeenCarsSelectors.getUsers))
this.observedCars$ = this.store.pipe(select(userObservedCarsSelectors.getUsers))
}
onSetObservedCar(carId:number):void{
let observed:ObservedCar = {id:null, carId:carId, userId:null}
this.store.dispatch(observedCarsActions.setObservedCar({carId}))
}
onSetNotObservedCar(carId:number):void{
this.store.dispatch(observedCarsActions.setNotObservedCar({carId}))
}
onSetObservedCars(cars:Car[]):void{
this.store.dispatch(carsActions.setCarsWithObserved({cars}))
}
onSetBrandChecked(brand:BrandCB):void{
this.store.dispatch(brandsActions.setBrandChecked({brand}))
}
onSetBrandsChecked(brands:BrandCB[]):void{
this.store.dispatch(brandsActions.setBrandsChecked({brands}))
}
onSetTypeChecked(typee:TypeCB):void{
this.store.dispatch(typesActions.setTypeChecked({typee}))
}
onSetTypesChecked(types:TypeCB[]):void{
this.store.dispatch(typesActions.setTypesChecked({types}))
}
public logout():void{
this.store.dispatch(statusActions.setRecentSeenCarsLoaded({loaded:false}))
}
}
export class GalleryComponent implements OnInit, DoCheck, OnChanges{
@Input() allCars:Car[]
@Input() brands:BrandCB[]
@Input() types:TypeCB[]
@Input() usersRatings:UserRating[]
@Input() recentSeenCars:Car[]
@Input() observedCars:ObservedCar[]
@Output() setObservedCarAction = new EventEmitter<any>()
@Output() setNotObservedCarAction = new EventEmitter<any>()
@Output() setObservedCarsAction = new EventEmitter<any>()
@Output() setBrandCount = new EventEmitter<any>()
@Output() setTypeCount = new EventEmitter<any>()
@Output() setBrandChecked = new EventEmitter<any>()
@Output() setTypeChecked = new EventEmitter<any>()
@Output() setBrandsChecked = new EventEmitter<any>()
@Output() setTypesChecked = new EventEmitter<any>()
filteredCars:Car[] = []
/* brandsCB:BrandCB[] = []
typesCB:TypeCB[] = [] */
user:User
iterableDiffer:IterableDiffer<any>
checkboxBrandAll:boolean = true
checkboxTypeAll:boolean = true
leftConteinerClass:string
faBars = faBars
constructor( private authService:AuthenticationService, private iterableDiffers: IterableDiffers){
this.iterableDiffer = iterableDiffers.find([]).create(null);
}
// evocata quando ci sono cambiamenti nelle proprietà di input
ngOnChanges(changes: SimpleChanges): void {
// c'è bisogno di chiamare filterCars perchè oltre a filtrare le auto aggiorna l'array in visualizzazione
changes.allCars ? this.filterCars(this.brands, this.types) : null
}
ngDoCheck(): void {
// used when observed buttons are pressed
let changes = this.iterableDiffer.diff(this.observedCars);
if (changes) {
this.user ? this.setObservedCars() : null
}
}
ngOnInit():void{
this.user = this.authService.currentUserValue
this.user ? this.setObservedCars() : null
this.initFilters()
this.filterCars(this.brands, this.types)
this.showNormalLeftConteiner()
window.addEventListener('resize', () => this.showNormalLeftConteiner())
}
// setta le checkbox degli "all" dei filtri a false se altre checkbox risultano selezionate
initFilters(){
let filtersBrands:boolean = false
let filtersTypes:boolean = false
this.brands.some( brand => brand.checked) ? filtersBrands = true : null
this.types.some( type => type.checked) ? filtersTypes = true : null
filtersBrands ? this.checkboxBrandAll = false : null
filtersTypes ? this.checkboxTypeAll = false : null
}
// operazioni da effettuara al cambiamento di una checkbox dei filtri.
checkboxChange(event, brand, type):void{
let name = event.target.name;
let checked = event.target.checked;
let brands:BrandCB[] = JSON.parse(JSON.stringify(this.brands))
let types:TypeCB[] = JSON.parse(JSON.stringify(this.types))
//BRANDS
if(name =='allBrands'){
if(checked == true){
brands.map(brand => brand.checked = false);
this.checkboxBrandAll = true
this.filterCars(brands, types)
brands = this.countBrands(brands)
types = this.countTypes(types)
this.setBrandsChecked.emit(brands)
this.setTypesChecked.emit(types)
}else{
this.checkboxBrandAll = true
}
} else if(name == 'otherBrands'){
brands = brands.map( b => {
if(b.id == brand.id){
return ({...brand, checked:checked})
}else{
return b
}
})
if(checked == true){
this.checkboxBrandAll = false;
}else
brands.some( b => b.checked) ? null : this.checkboxBrandAll = true
this.filterCars(brands, types)
brands = this.countBrands(brands)
types = this.countTypes(types)
this.setBrandsChecked.emit(brands)
this.setTypesChecked.emit(types)
}
// TYPES
if(name =='allTypes'){
if(checked == true){
types.map(type => type.checked = false)
this.checkboxTypeAll = true
this.filterCars(brands, types)
brands = this.countBrands(brands)
types = this.countTypes(types)
this.setBrandsChecked.emit(brands)
this.setTypesChecked.emit(types)
}else{
this.checkboxTypeAll = true
}
} else if(name == 'otherTypes'){
types = types.map( t => {
if(t.id == type.id){
return ({...type, checked:checked})
}else{
return t
}
})
if(checked == true){
this.checkboxTypeAll = false;
}else
types.some( t => t.checked) ? null : this.checkboxTypeAll = true
this.filterCars(brands, types)
brands = this.countBrands(brands)
types = this.countTypes(types)
this.setBrandsChecked.emit(brands)
this.setTypesChecked.emit(types)
}
}
// aggiorna la proprietà "observed" di allCars
setObservedCars():void{
let allCars:Car[] = JSON.parse(JSON.stringify(this.allCars))
let observedCars:ObservedCar[] = [...this.observedCars]
allCars.map( car => {
// se la car è osservata, setta "observed" a true
observedCars.some( obs => obs.carId == car.id) ? car.observed = true : car.observed = false
})
this.setObservedCarsAction.emit(allCars)
}
// aggiorna l array per la gallery (this.filteredCars) con l'array modificato eventualmente nei filtri o nella proprietà observed (this.allCars)
filterCars(brands:BrandCB[], types:TypeCB[]):void{
let allCars = [...this.allCars];
const checkedBrands = brands.filter(brand => brand.checked);
const checkedTypes = types.filter(type => type.checked);
let filteredCars:Car[];
if(!this.checkboxBrandAll && !this.checkboxTypeAll){
filteredCars = allCars.filter(car => checkedBrands.find(brand => brand.name === car.brand) && checkedTypes.find(type => type.name === car.type));
} else if(!this.checkboxBrandAll && this.checkboxTypeAll){
filteredCars = allCars.filter(car => checkedBrands.find(brand => brand.name === car.brand));
}else if(this.checkboxBrandAll && !this.checkboxTypeAll){
filteredCars = allCars.filter(car => checkedTypes.find(type => type.name ===car.type));
}else{
filteredCars = [...allCars];
}
this.filteredCars = [...filteredCars]
}
// conta le occorrenze di ogni brand, ad esempio ferrari(2)
countBrands(brands:BrandCB[]):BrandCB[]{
let br:BrandCB[] = brands.map( brand => {
let count = 0;
this.filteredCars.forEach( car => {
brand.name == car.brand ? count++ : null
})
brand.count = count;
return brand
})
return br
}
// conta le occorrenze di ogni type, ad esempio jeep(2)
countTypes(types:TypeCB[]):TypeCB[]{
let ty:TypeCB[] = types.map( type => {
let count = 0;
this.filteredCars.forEach( car => {
type.name == car.type ? count++ : null
})
type.count = count;
return type
})
return ty
}
showMobileLeftConteiner():void{
this.leftConteinerClass = 'show-mobile-left-conteiner'
}
showNormalLeftConteiner():void{
if(window.innerWidth >= 1051){
this.leftConteinerClass = 'show-normal-left-conteiner'
}else{
this.hideLeftContenier()
}
}
hideLeftContenier():void{
this.leftConteinerClass = 'hide-left-conteiner'
}
onSetObservedCar(carId:number):void{
this.setObservedCarAction.emit(carId)
}
onSetNotObservedCar(carId:number):void{
this.setNotObservedCarAction.emit(carId)
}
}
导出类GalleryComponent实现OnInit、DoCheck和OnChanges{
@输入()所有汽车:汽车[]
@输入()品牌:BrandCB[]
@Input()类型:TypeCB[]
@Input()usersRatings:UserRating[]
@Input()recentSeenCars:Car[]
@Input()observedCars:observedCars[]
@Output()setObservedCarAction=新的EventEmitter()
@Output()setNotObservedCarAction=new EventEmitter()
@Output()setObservedCarsAction=new EventEmitter()
@Output()setBrandCount=新的EventEmitter()
@Output()setTypeCount=新的EventEmitter()
@Output()setBrandChecked=neweventemitter()
@Output()setTypeChecked=neweventemitter()
@Output()setBrandsChecked=neweventemitter()
@Output()setTypesChecked=新的EventEmitter()
过滤卡:汽车[]=[]
/*brandsCB:BrandCB[]=[]
类型Cb:TypeCB[]=[]*/
用户:用户
iterableDiffer:iterableDiffer
checkboxBrandAll:boolean=true
checkboxTypeAll:boolean=true
LeftContentinerClass:字符串
faBars=faBars
构造函数(私有authService:AuthenticationService,私有iterableDiffers:iterableDiffers){
this.iterableDiffer=iterableDiffer.find([]).create(null);
}
//evocata quando ci sono cambiamenti nelle proprietádi input
ngOnChanges(更改:SimpleChanges):无效{
//c'bisogno di chiamare filterCars在Visualizazione中安装了一个过滤自动聚集数组
changes.allCars?this.filterCars(this.brands,this.types):null
}
ngDoCheck():void{
//按下观察按钮时使用
让changes=this.iterableDiffer.diff(this.observedCa