Ionic(angular)应用程序无法将值指派给属性,因为它认为属性是只读的,但实际上并非如此

c8ib6hqw  于 2022-12-08  发布在  Ionic
关注(0)|答案(1)|浏览(147)

I'm creating some app using Ionic with Angular and I'm facing some strange issue with assigning properties.
So, I have simple component which is rendering some filters for user to choose:

<ng-container *ngFor="let filter of filters; let idx = index">
    <div class="filter-wrapper">
        {{ filter.text | transloco | uppercase }}
        <div class="icon-wrapper" (click)="handleFilterClick(idx, $event)">
            <app-icon-button 
                [color]="filter.isActive ? activeIconColor : inActiveIconColor" 
                [src]="filter.iconSrc"
            >
            </app-icon-button>
        </div>
     </div>
</ng-container>

Filters array looks like this:

filters: Filter[];

constructor(
    private store: Store<AppState>,
) {}

ngOnInit() {
    this.filters = [
        {
            iconSrc: 'assets/icons/white-filters-icons/parking.svg',
            text: 'shared.attribute.parking',
            isActive: false,
            filter: Attribute.PARKING,
        },
        {
            iconSrc: 'assets/icons/white-filters-icons/wc.svg',
            text: 'shared.attribute.wc',
            isActive: false,
            filter: Attribute.WC,
        },
        {
            iconSrc: 'assets/icons/white-filters-icons/food.svg',
            text: 'shared.attribute.food',
            isActive: false,
            filter: Attribute.FOOD,
        }
    ]
}

Filters are rendered correctly without any issues, but then I have a function which handles filters clicking and it looks like this:

handleFilterClick = (idx: number, e: MouseEvent): void => {
    this.filters[idx].isActive = !this.filters[idx].isActive;
    const selectedFilters = [...this.filters.filter(el => el.isActive)];
    this.store.dispatch(new SetSelectedFilters({ filters: selectedFilters }));
    e.stopImmediatePropagation();
};

When I click first time on any of filters it works correctly, filter color is being changed, dispatch action is being executed, but then if I click at any previously clicked filter it just stops working and I can see an error in console which says: "Attempted to assign to readonly property.". It works fine only if I delete line with store dispatch function

this.store.dispatch(new SetSelectedFilters({ filters: selectedFilters }));

Can anybody tell me how it is possible?
EDIT:
SetSelectedFilters and reducer are created like this:

export enum ActionTypes {
    SET_SELECTED_FILTERS = '[Map] Set selected filters',
}

export class SetSelectedFilters implements Action {
    readonly type = ActionTypes.SET_SELECTED_FILTERS;
    constructor(public payload: { selectedFilters: Filter[] }) { }
}

export type Actions = SetSelectedFilters;

Reducer here:

export interface MapState {
    selectedFilters: Filter[];
};

export const initialState: MapState = {
    selectedFilters: [],
};

export const reducer = (
    state = initialState,
    action: fromMap.Actions
): MapState => {
    switch (action.type) {
        case fromMap.ActionTypes.SET_SELECTED_FILTERS: {
            return {
                ...state,
                selectedFilters: action.payload.selectedFilters,
            };
        }
        default: {
            return state;
        }
    }
};
pgccezyw

pgccezyw1#

You have this error since in the Ngrx runtime checks the strictActionImmutability is set to true (it will be automatically disabled in production builds).
https://ngrx.io/guide/store/configuration/runtime-checks
So, you can set this flag to false or you need to ensure the immutability of the action object (maybe by making a deep clone of the filters ?).

相关问题