Javascript 无法分配给只读属性';关闭';对象的';[对象对象]';
这几天来我一直在绞尽脑汁,但我找不到发生这种情况的原因 因此,我得到以下错误消息: TypeError:无法分配给对象“[object]”的只读属性“closed” 如您所见,它发生在sendProposal函数的civilliability-step3.component.ts中:Javascript 无法分配给只读属性';关闭';对象的';[对象对象]';,javascript,angular,Javascript,Angular,这几天来我一直在绞尽脑汁,但我找不到发生这种情况的原因 因此,我得到以下错误消息: TypeError:无法分配给对象“[object]”的只读属性“closed” 如您所见,它发生在sendProposal函数的civilliability-step3.component.ts中: civilliability-step3.component.ts @Component({ selector: 'app-civilliability-step3', templateUrl: './c
civilliability-step3.component.ts
@Component({
selector: 'app-civilliability-step3',
templateUrl: './civilliability-step3.component.html',
styleUrls: ['./civilliability-step3.component.scss']
})
export class CivilliabilityStep3Component implements OnInit, OnDestroy {
@Output() modelChange = new EventEmitter<CivilLiabilityRequestType>();
@Output() onCloseForm = new EventEmitter();
@Input() model: CivilLiabilityRequestType;
public formGroup: FormGroup;
private closedProposalSub: Subscription;
constructor(private formBuilder: FormBuilder, private store: Store) {}
ngOnInit() {
this.buildForm();
if (this.model !== undefined && this.model.details.closed) {
disableFormGroup(this.formGroup);
}
this.closedProposalSub = this.store
.select(ProposalsState.closedProposalResult)
.subscribe(val => {
if (val !== undefined) {
this.modelChange.emit(val);
this.onCloseForm.emit();
}
});
}
ngOnDestroy() {
if (this.closedProposalSub && !this.closedProposalSub.closed) {
this.closedProposalSub.unsubscribe();
}
this.store.dispatch(new ResetClosedProposalResult());
}
sendProposal() {
this.model.details.closed = true;
this.store.dispatch(new CloseProposal(this.model));
}
closeForm() {
disableFormGroup(this.formGroup);
}
private buildForm() {
this.formGroup = this.formBuilder.group({});
}
}
@Component({
selector: 'app-detail',
templateUrl: './detail.component.html',
styleUrls: ['./detail.component.scss']
})
export class DetailComponent implements OnInit {
public tabs: Tab[] = [];
public selectedTabIndex = 0;
public quote?: QuoteData;
public quoteModel: QuoteData;
public originalModel: any[];
public readonly = false;
@Input() public requestType;
constructor(private activeRoute: ActivatedRoute) {}
ngOnInit() {
const snapshot = this.activeRoute.snapshot;
this.originalModel = snapshot.data['model'];
if (this.originalModel) {
this.tabs = this.createTabsFromQuoteModel(this.originalModel);
}
}
private createTabsFromQuoteModel(model: any): Tab[] {
let tabs: Tab[] = [];
for (const key of Object.keys(model)) {
const element = model[key];
let type: RequestTypes;
let proposalData: IRequestData = {};
if (key === 'civilLiability') {
type = RequestTypes.CivilLiability;
proposalData.type = RequestTypes.CivilLiability;
proposalData.data = element;
}
tabs = [...tabs, { type: type, name: '', tabData: proposalData }];
proposalData = {};
}
return tabs;
}
}
我尝试以不同的方式分配真值,因为我想可能无法将它直接添加到模型中,这是一个输入。但这也没用
sendProposal() {
const detailsModel = this.model.details;
detailsModel.closed = true; // <-- same error
this.model.details = detailsModel;
const tmpModel = this.model;
tmpModel.details.closed = true; // <-- same error
this.model = tmpModel;
// this.model.details.closed = true;
this.store.dispatch(new CloseProposal(this.model));
}
更新2:显示此模型的来源:
民事责任详情.component.ts
export class CivilliabilityProposalDetailComponent implements OnInit, OnDestroy {
@Input() model: CivilLiabilityRequestType;
@Input() tab: Tab;
@Input() tabs: Tab[] = [];
@Input() selectedTabIndex;
@Input() idx: number;
constructor() {}
ngOnInit() {}
ngOnDestroy() {
this.model = getEmptyCivilLiabilityRequest();
}
}
detail.component.html
<app-civilliability-step3
(onCloseForm)="step1.closeForm(); step2.closeForm(); step3.closeForm()"
[(model)]="model"
#step3></app-civilliability-step3>
<mat-tab *ngFor="let tab of tabs; let idx = index">
...
<app-civilliability-proposal-detail
[model]="tab.tabData.data"
[tab]="tab"
[tabs]="tabs"
[selectedTabIndex]="selectedTabIndex"
[idx]="idx"
>
</app-civilliability-proposal-detail>
...
</mat-tab>
为了让我们保持头脑清醒,我们对结构进行了概述:
<app-detail>
<mat-tab *ngFor="let tab of tabs; let idx = index">
<app-civilliability-proposal-detail [model]="tab.tabData.data">
<app-civilliability-step3 [(model)]="model" ></app-civilliability-step3>
</app-civilliability-step3
</app-civilliability-proposal-detail>
</mat-tab
</app-detail>
我认为发生这种情况是因为您无法修改存储在状态(ngRx)中的对象,您可以尝试以下操作:
sendProposal() {
this.store.dispatch(new CloseProposal(Object.assign({}, this.model, {
details: { closed: true }
})));
}
必须使用Object.assign方法更改对象的值,如下所示:
Object.assign(target, source);
CivilLiabilityRequestType
的closed
属性为只读,因此无法分配。您能显示型号吗?添加了型号。但我不确定这里的属性是否为只读。我可能是错的ofc。从这个角度来看,错误是不言自明的:TypeError:无法分配给对象“[object]”的只读属性“closed”。这意味着创建CivilLiabilityRequestType
实例的人正在将该属性设置为只读。它是在哪里创建的?如果您将民事责任详细信息.component.ts
发布到模型正在以任何方式更改的位置,这将非常有用添加更多可能有帮助的代码,我将把它标记为正确的解决方案,因为这在不同的位置以某种方式解决了问题。但是你是对的,你不能修改来自该状态的对象。我不知道NgRx状态是只读的。。。。。谢谢你的帮助……天才!非常感谢。我已经挣扎了一整天。最近我遇到了同样的错误,我花了一分钟的时间才发现,对从ngrx存储中获取的对象进行变异不仅是违法的,而且在对象存储到ngrx后继续进行变异也是违法的。在将对象传递给ngrx进行存储(相当于此处的this.model
)之后,我必须创建一个新的本地副本,以避免进一步改变ngrx作为状态保存的对象。“ngrx的第一条规则,不变性。此strictStateImmutability检查验证开发人员是否试图修改状态对象。”你可以关掉它,但是你应该考虑这是否真的是你想要的。文档中的示例对于定义用于更改状态的减速器也很有帮助。
Object.assign(target, source);