【问题标题】:Angular 2 - Binding Component to multiple valuesAngular 2 - 将组件绑定到多个值
【发布时间】:2017-08-03 14:22:01
【问题描述】:

我正在尝试在 Angular 2 中实现日期范围选择器。

我已经有一个可以工作的小部件,我必须将它链接到@angular/forms 子系统。

我希望能够将两个输出值(比如rangeStartrangeEnd)绑定到包含表单状态的两个不同属性。

有没有办法可以配置 NgModel 设置来完成此操作?

另一种方法是绑定 DateRange 类型的单个属性:

type DateRange = {
    from: Date,
    to: Date
};

我不知道这是否可能。

关于如何完成此任务的任何建议?

编辑:

我拥有的是一个 jQuery 派生的 JS 组件,它公开了一个 onChange,如下所示:

component.on('change', (eventData) => {
  // here I have eventData.from and eventData.to as Date values
});

我想将这种处理程序集成到对 Angular 友好的组件中。 但是,我不能简单地这样做:

<my-date-range-picker name"xyz" [(NgModel)]="aDateRangeValue"></my-date-range-picker>

因为,AFAICT,变更检测不适用于复合值。 我应该在我的组件中公开什么?两个EventEmitters?我可以以某种方式利用NgModel 吗?

【问题讨论】:

  • 你能给我们提供一些代码或更好的解释吗,因为我不确定你想在这里完成什么。
  • 我试图更好地描述我的场景。基本上我有两个值,我想通过 NgModel 或其他替代方法将它们公开为输出
  • 我的回答对您的问题有帮助吗?您可以根据需要将它们设为 EventEmitters 或什至 Subjects(来自 rxjs)。
  • 张贴一个你到目前为止所拥有的东西。那样我会更容易工作......
  • @JGFMK 我有其他 5 个控件绑定到简单值,通过 ControlValueAccessor 接口将值公开给表单模块。 ControlValueAccessor 提供了很多好处,但似乎仅限于公开单个值。现在我想知道如何使用 2 个值(或者换句话说,由两个日期定义的单个值)做同样的事情(实现 ControlValueAccessor)。

标签: angular angular-ngmodel angular2-ngmodel


【解决方案1】:

如果你想创建你自己的ngModel 像双向数据绑定,这就是你应该做的:

@Component()
export class MyComponent {

      myValue = 0;

      @Output()
      myValueChange = new EventEmitter();

      @Input()
      get myValue() {
             return this.myValue;
      }

      set myValue(val) {
           this.myValue= val;
           this.myValueChange.emit(this.myValue);
      }
}

现在您可以按如下方式使用它,并实现双向数据绑定:

<my-component [(myValue)]="someExpression"></my-component>

添加一个简单教程的链接:http://www.angulartraining.com/blog/tutorial-create-your-own-two-way-data-binding-in-angular/

【讨论】:

    【解决方案2】:

    好吧,事实证明,您可以拥有任何类型的模型。

    所以,我使用了来自this article 的基类,这里是最相关的:

    export class ValueAccessorBase<T> implements ControlValueAccessor {  
      private innerValue: T;
    
    
      private changed = new Array<(value: T) => void>();
      private touched = new Array<() => void>();
    
    
      get value(): T {
        return this.innerValue;
      }
    
    
      set value(value: T) {
        if (this.innerValue !== value) {
          this.innerValue = value;
          this.changed.forEach(f => f(value));
        }
      }
    
    
      touch() {
        this.touched.forEach(f => f());
      }
    
    
      writeValue(value: T) {
        this.innerValue = value;
      }
    
    
      registerOnChange(fn: (value: T) => void) {
        this.changed.push(fn);
      }
    
    
      registerOnTouched(fn: () => void) {
        this.touched.push(fn);
      }
    }
    

    即使T 是一个具有fromto 属性的类,在我的情况下,这也会发生:

    @Component(
      ...
    )
    class DateRangeComponent extends ValueAccessorBase<DateRange> {
      ... implementation
    
      // somewhere after the view init:
      jqueryComponent.on('change', (eventData) => {
       // here I have eventData.from and eventData.to as Date values
       this.value = {
         from: eventData.from,
         to: eventData.to
       };
      });
    }
    

    所以,如果其他人都偶然发现了这个问题,答案是:继续编写自己的组件。

    附带说明,这在仅使用表单来准备要在 Ajax 调用中发送的 Json 对象时效果最佳。老式的表单编码提交将不那么线性。

    【讨论】:

      【解决方案3】:

      您可以使用两个Output 指令。

      &lt;my-date-range-picker name"xyz" [dateTo]="dateTo" [dateFrom]="dateFrom"&gt;&lt;/my-date-range-picker&gt;

      在你的组件中你会拥有

      import { Output } from '@angular/core';
      .
      .
      @Output() dateTo: any; // EventEmitter, Subject, Number, String, doesn't matter ...
      @Output() dateFrom: any;
      

      这里参考了使用InputOutput的组件交互

      Component Interaction

      【讨论】:

      • 是的,但是我可以将验证和表单绑定附加到简单的输出指令吗?我试图了解可能的方法有哪些限制。
      • 如果您将它们用作 EventEmitters 或 Subjects,您可以订阅它们并对这些事件使用验证
      猜你喜欢
      • 2018-04-16
      • 1970-01-01
      • 1970-01-01
      • 2018-09-20
      • 1970-01-01
      • 2019-03-07
      • 2018-11-27
      • 1970-01-01
      • 2017-10-26
      相关资源
      最近更新 更多