[英]Angular 2 + ngrx/store: one-way binding to an <input>
在<input>
上通過[ngModel]
使用單向綁定時,在<input>
鍵入字符總是會在<input>
的值中添加字符。 問題是如果[ngModel]
表達式繼續返回其現有值,則不會刷新<input>
值。
這是一個簡單的例子:
@Component({
selector: 'my-component',
template: `
<input type="text" [ngModel]="foo.bar" />
`
})
export class MyComponent {
private foo = {
bar: 'baz'
};
}
我希望無論用戶輸入如何,輸入總是顯示“baz”,但事實並非如此。
我正在尋找這種行為的原因是ngrx / store / redux應用程序,其中<input>
的值應該由單向流動的狀態決定。 我在Plunker上創建了一個示例用例 ,其中Misko Hevery的描述不應該是可編輯的。 模型確實沒有改變,但<input>
顯示用戶<input>
內容。
在“No trackBy”部分,它可以正常工作,但只是因為Angular正在重繪所有強制重新評估的DOM元素(但這不是解決方案)。 將disabled
或readonly
屬性添加到<input>
對我來說不是一個可接受的答案,因為組件應該不知道不允許更改此字段的潛在復雜狀態邏輯。
我在React Redux中看到過這種行為,我想知道如果我們無法阻止用戶改變他們自己的視圖,我們如何在Angular 2中使用單向綁定。
因為當從狀態返回的值相同時不會觸發ChangeDetection,所以唯一直接的方法是通過綁定到組件構造函數中商店的customer.descriptionLocked屬性的customerDescriptionLocked屬性集。 我知道你不希望組件只使用readonly,因為你不希望組件知道狀態確定鎖的邏輯。 通過綁定到customerDescriptionLocked屬性,組件仍然不知道狀態的設置邏輯。
<input type="text" placeholder="Description" [ngModel]="record.customerDescription"
[readonly]="record.customerDescriptionLocked" (ngModelChange)="updateDescription(record, $event)" />
組件構造函數:
constructor(public store: Store<AppState>, private ref: ChangeDetectorRef){
this.customerState = store.select('customer');
this.customerState.subscribe((customerState:CustomerState) => {
this.dashboardRecords = customerState.customers.map((customer:Customer):DashboardRecord => {
return {
customerId: customer.id,
customerName: `${customer.personalInfo.firstName} ${customer.personalInfo.lastName}`,
customerDescription: customer.description,
customerDescriptionLocked: customer.descriptionLocked,
customerUpdateCount: customer.updated
};
})
});
}
@Component({
selector: 'my-component',
template: `
<input type="text" [value]="foo.bar" />
//[ngModel] is for two way binding
`
})
export class MyComponent {
private foo = {
bar: 'baz'
};
}
@Component({
selector: 'my-component',
template: `
<input type="text" [value]="foo.bar" (keydown) = "$event.preventDefault();"/>
//add preventDefault() to keydown event to prevent user from changing the value shown in input field
`
})
export class MyComponent {
private foo = {
bar: 'baz'
};
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.