【问题标题】:How to update Angular 2 Reactive form field when changes occurred outside of Angular world如何在 Angular 世界之外发生更改时更新 Angular 2 Reactive 表单字段
【发布时间】:2017-11-17 10:19:01
【问题描述】:

我最近开始学习 Angular 2,我正在努力理解如何正确地将外部世界发生的变化与 Angular 反应式表单联系起来。

具体来说,我对以下示例有疑问: 我想创建一个指令,通过预先输入的 jQuery 插件提供的自动完成功能来增强输入。我的指令如下所示:

@Directive({
  selector: '[myTypeahead]'
})
class TypeAheadDirective implements AfterViewInit 
{
  constructor(private el: ElementRef) {
  }
  //this will be used as a parameter to source, it is not important for this example
  @Input() myTypeahead: string;
  ngAfterViewInit() {
    let source = new Bloodhound({
      datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
      queryTokenizer: Bloodhound.tokenizers.whitespace,
      prefetch: 'http://twitter.github.io/typeahead.js/data/films/post_1960.json'
    });
    $(this.el.nativeElement).typeahead(null, {source, display: 'value'});
  }
}

然后我将它绑定到我的组件中的输入元素中,如下所示:

@Component({
  selector: 'my-app',
  template: `
    <form (ngSubmit)="save()" [formGroup]="someForm">
      <h2>Hello {{name}}</h2>
      <input formControlName="name" myTypeahead="'http://someRemoteUrl'"/>
    </form>

    <div class="example">Form model: {{someForm.value | json}}</div>
  `,
})
export class App implements OnInit {
  someForm: FormGroup;
  name:string;
  constructor(private fb: FormBuilder) {
    this.name = `Angular! v${VERSION.full}`
  }

  ngOnInit() {
    this.someForm = this.fb.group({
      name: ''
    });
  }

  save(){

  }
}

Here is a plunker with my example

当我开始在输入中输入内容时 - 我的FormGroup 的绑定按预期工作。但是当我从自动完成中选择一些提示时 - 它会更新输入,但不会将更新后的值传播到我的表单组。

所以我的问题是,是否可以向表单组发出指令中发生的更改的信号?

一个可能的解决方案是制作一个实现 ControlValueAccessor 的组件来通知更改,但我想通过一个接受数据源 URL 的指令来保持这个简单。

【问题讨论】:

  • @yurzui,感谢您发布此信息。因此,它将是一个专门用于响应式表单元素的指令。我认为它回答了我的问题,所以我愿意在它发布时接受它。

标签: jquery angular angular2-forms angular2-directives angular-directive


【解决方案1】:

内部指令:

您可以使用@Output 发送事件并在表单中捕获它

@Output typeaheadResult = new EventEmitter(); 

...

// Whenever user selects a result dispatch the event 
this.typeaheadResult.emit(changedInput);

在您的 HTML 中,您可以捕获它

 <input formControlName="name"
          myTypeahead="'http://someRemoteUrl'"
          (typeaheadResult)="doSomething()"
           />

【讨论】:

  • 感谢您的回答,这是一个选项,但我想省略它,因为它使指令的使用变得复杂,可能是在外部触发事件的情况下 - 最好创建一个组件.
  • 我不明白,这就是 Angular 官方对事件的建议吧?
  • 在搜索我的情况大约 3 小时后,我没有看到 angular 的任何官方建议,所以这只是我的意见。我只是说我认为这个解决方案将字段值设置为指令的使用者,这在我需要在整个页面中进行大量自动完成时并不理想,因此最好编写一个组件而不是输出事件指令。
  • 好的,我明白你的意思了。我猜你已经得到了解决方案,否则我们可以检查它在 NgModel 实现中是如何完成的。
猜你喜欢
  • 2017-05-06
  • 2016-03-26
  • 2017-06-30
  • 1970-01-01
  • 2017-12-30
  • 2017-05-28
  • 1970-01-01
  • 1970-01-01
  • 2021-04-19
相关资源
最近更新 更多