繁体   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