Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2: use [(ngModel)] with [ngModelOptions]="{standalone: true}" to link to a reference to model's property

Let's say I have a typescript object of type Mailtype like following:

export class Mailtype {
  constructor(
    public name?: string,
    public locale?: string,
    public email?: string,
    public properties? : Property[]
  ) {  }
}

Where its "properties" field is an array of type Property:

export class Property {
  constructor(
    public name?: string,
    public type?: string,
    public example?: string,
    public required?: boolean,
    public masked?: boolean
  ) {  }
}

Now in my component I have a single Mailtype object and the html has a form element used for editing and adding to the properties array of the Mailtype:

<form>
   <tr *ngFor="let property of model.properties; let i=index">
          <td>
            <input type="text" [(ngModel)]="property.name" required>
          </td>
  </tr>
  <button (click)="onAddProperty()">Add property</button>
</form>

component:

export class MailtypeComponent {
  model : Mailtype;
  constructor() {
    this.model = new Mailtype('','','',[]);
    this.model.properties.push(new Property());
  }

  onAddProperty() {
    this.model.properties.push(new Property());
  }
}

I was wondering if I'm not allowed to use [(ngModel)] to link to a reference "property" to the array element in the array, especially at the same time I'm iterating the array? Because it throws the following error for the above code:

ORIGINAL EXCEPTION: If ngModel is used within a form tag, either the name attribute must be set
                      or the form control must be defined as 'standalone' in ngModelOptions.

                      Example 1: <input [(ngModel)]="person.firstName" name="first">
                      Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">

So it's suggesting I use either [ngModelOptions]="{standalone: true}" or add a name field to the html. And it looks like [ngModelOptions]="{standalone: true}" works in this case. What does standalone: true actually mean since I cannot find any documentation about it?

like image 356
Calvin Hu Avatar asked Jul 14 '16 04:07

Calvin Hu


People also ask

What is the use of ngModelOptions ]= standalone true?

If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions. ERROR Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.

Which module do you need to import to use [( ngModel )]?

NgModule: Module used by NgModel is: FormsModule.

How do you use ngModelOptions?

The ng-model-options directive is used to control the binding of an HTML form element and a variable in the scope. You can specify that the binding should wait for a specific event to occur, or wait a specific number of milliseconds, and more, see the legal values listed in the parameter values below.

Can we use ngModel without form?

See the example for using NgModel as a standalone control. standalone: When set to true, the ngModel will not register itself with its parent form, and acts as if it's not in the form. Defaults to false.


2 Answers

Using @angular/forms when you use a <form> tag it automatically creates a FormGroup.

For every contained ngModel tagged <input> it will create a FormControl and add it into the FormGroup created above; this FormControl will be named into the FormGroup using attribute name.

Example:

<form #f="ngForm">
    <input type="text" [(ngModel)]="firstFieldVariable" name="firstField">
    <span>{{ f.controls['firstField']?.value }}</span>
</form>

Said this, the answer to your question follows.

When you mark it as standalone: true this will not happen (it will not be added to the FormGroup).

Reference: https://github.com/angular/angular/issues/9230#issuecomment-228116474

like image 115
zpul Avatar answered Oct 11 '22 22:10

zpul


For me the code:

<form (submit)="addTodo()">
  <input type="text" [(ngModel)]="text">
</form>

throws error, but I added name attribute to input:

<form (submit)="addTodo()">
  <input type="text" [(ngModel)]="text" name="text">
</form>

and it started to work.

like image 23
Natalia Avatar answered Oct 11 '22 22:10

Natalia