簡體   English   中英

Angular 2 + ngrx / store:單向綁定到<input>

[英]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元素(但這不是解決方案)。 disabledreadonly屬性添加到<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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM