在Angular 2+ Reactive Form

时间:2017-12-04 03:00:18

标签: angular angular-reactive-forms angular2-ngmodel

我的页面上有一张被动表格。

以下是代码摘要:

<div class="container">
<form [formGroup]="transactionForm" (ngSubmit)="onSubmit(transactionForm)">
     <div formGroupName="userInfoGroup" class="form-group">
          <input formControlName="name" class="form-control" placeholder="Larry" id="name"> 
     </div>
     ...
</form>   
</div>

这里变得棘手。我希望用户能够输入推荐他们的人的信息(我们的数据库中可能存在也可能不存在)。因此,我想使用ng-bootstrap typeahead为现有用户提供搜索的方法。

所以我复制了ng-bootstrap中的htmlts代码,现在我的模板看起来像

<div class="container">
<form [formGroup]="transactionForm" (ngSubmit)="onSubmit(transactionForm)">
     <div formGroupName="userInfoGroup" class="form-group">
          <input formControlName="name" class="form-control" placeholder="Larry" id="name"> 
     </div>
     <input id="typeahead-http" type="text" class="form-control" [(ngModel)]="model" [ngbTypeahead]="searchForReferrer" placeholder="Search for Referrer" />
     ...
</form>   
</div>

当我现在运行时,我得到错误:

RegisterTransaction.html:154 ERROR TypeError: Cannot read property 'lift' of undefined
    at tapOperatorFunction (tap.js:52)
    at _do (do.js:48)
    at NgbTypeahead.webpackJsonp.../../../../@ng-bootstrap/ng-bootstrap/typeahead/typeahead.js.NgbTypeahead.ngOnInit (typeahead.js:73)
    at checkAndUpdateDirectiveInline (core.es5.js:10843)
    at checkAndUpdateNodeInline (core.es5.js:12341)
    at checkAndUpdateNode (core.es5.js:12284)
    at debugCheckAndUpdateNode (core.es5.js:13141)
    at debugCheckDirectivesFn (core.es5.js:13082)
    at Object.View_RegisterTransaction_0._co [as updateDirectives] (RegisterTransaction.html:163)
    at Object.debugUpdateDirectives [as updateDirectives] (core.es5.js:13067)
  [1]: https://ng-bootstrap.github.io/#/components/typeahead/examples

如果我删除[ngbTypeahead]="searchForReferrer",我就会

RegisterTransaction.html:154 ERROR Error: 
      ngModel cannot be used to register form controls with a parent formGroup directive.  Try using
      formGroup's partner directive "formControlName" instead.  Example:


    <div [formGroup]="myGroup">
      <input formControlName="firstName">
    </div>

    In your class:

    this.myGroup = new FormGroup({
       firstName: new FormControl()
    });

      Or, if you'd like to avoid registering this form control, indicate that it's standalone in ngModelOptions:

      Example:


    <div [formGroup]="myGroup">
       <input formControlName="firstName">
       <input [(ngModel)]="showMoreControls" [ngModelOptions]="{standalone: true}">
    </div>


    at Function.webpackJsonp.../../../forms/@angular/forms.es5.js.TemplateDrivenErrors.modelParentException (forms.es5.js:4110)
    at NgModel.webpackJsonp.../../../forms/@angular/forms.es5.js.NgModel._checkParentType (forms.es5.js:4430)
    at NgModel.webpackJsonp.../../../forms/@angular/forms.es5.js.NgModel._checkForErrors (forms.es5.js:4417)
    at NgModel.webpackJsonp.../../../forms/@angular/forms.es5.js.NgModel.ngOnChanges (forms.es5.js:4324)
    at checkAndUpdateDirectiveInline (core.es5.js:10840)
    at checkAndUpdateNodeInline (core.es5.js:12341)
    at checkAndUpdateNode (core.es5.js:12284)
    at debugCheckAndUpdateNode (core.es5.js:13141)
    at debugCheckDirectivesFn (core.es5.js:13082)
    at Object.View_RegisterTransaction_0._co [as updateDirectives] (RegisterTransaction.html:163)

如何在现有的被动形式中正确使用此搜索?

2 个答案:

答案 0 :(得分:3)

感谢@Aluan Haddad,他促使我确保我的代码完全与示例代码相同,我最终意识到它确实相同。我无意中在箭头函数的return部分周围添加了花括号。

所以而不是

search = (text$: Observable<string>) =>
    text$
      .debounceTime(300)
      .distinctUntilChanged()
      .do(() => this.searching = true)
      .switchMap(term =>
        this._service.search(term)
          .do(() => this.searchFailed = false)
          .catch(() => {
            this.searchFailed = true;
            return Observable.of([]);
          }))
      .do(() => this.searching = false)
      .merge(this.hideSearchingWhenUnsubscribed);

我有

search = (text$: Observable<string>) => {
    text$
      .debounceTime(300)
      .distinctUntilChanged()
      .do(() => this.searching = true)
      .switchMap(term =>
        this._service.search(term)
          .do(() => this.searchFailed = false)
          .catch(() => {
            this.searchFailed = true;
            return Observable.of([]);
          }))
      .do(() => this.searching = false)
      .merge(this.hideSearchingWhenUnsubscribed);
}

答案 1 :(得分:0)

解决方案仅在错误消息中给出。您不能在form-group中使用ngModel。如果要使用ngModel,则需要指定该元素的独立性:通过在该元素中传递[ngModelOptions] =“{standalone:true}”来实现。您只需将该元素编写为:

<input id="typeahead-http" type="text" class="form-control" [(ngModel)]="model" [ngModelOptions]="{standalone: true}" [ngbTypeahead]="searchForReferrer" placeholder="Search for Referrer" />

这可以解决您的问题。

相关问题