Reputation: 4840
I'm running into a place where the model binding on Angular2 is not binding as I expect, and I'm having problems determining where I went awry.
I have an array of objects as follows:
commands = [
{
"id": 2,
"command": "!first",
"action": "This is the first command. You found it!",
"reply": false
},
{
"id": 5,
"command": "!hi",
"action": "Hello, how are you today?",
"reply": true
},
...
];
The view template is as follows (clipped for brevity, only showing tags with relevant Angular2 info):
<form #commandForm="ngForm">
<tr *ngFor="#cmd of commands">
<td *ngIf=" ! isEditingCommand(cmd)">{{ cmd.command }}</td>
<td *ngIf="isEditingCommand(cmd)">
<input type="text" class="form-control" placeholder="!command" required [(ngModel)]="cmd.command" (ngModelChange)="cmd.command=cleanCommand($event)" ngControl="cmd" #cmd="ngForm">
</td>
<td *ngIf=" ! isEditingCommand(cmd)">{{ cmd.action }}</td>
<td *ngIf="isEditingCommand(cmd)">
<textarea class="form-control" rows="1" placeholder="Text to display." required [(ngModel)]="cmd.action" ngControl="action" #action="ngForm"></textarea>
</td>
</tr>
</form>
When isEditingCommand(cmd) === false
, rows show up as follows:
When isEditingCommand(cmd) === true
, this is what I get:
I have changed both cmd
and cmd.command
to various names, in case command
is a reserved word for Angular2, to no avail. When I put {{ cmd | json }}
in the view, I receive this exception:
EXCEPTION: TypeError: Converting circular structure to JSON in [
{{ cmd | json }}
in CommandComponent@24:199]
I am unable to determine how this could have a circular structure, unfortunately. Even going through the Chrome Inspector I am not finding a place where it might be circular.
To assist, here are the functions that are defined in the view (TypeScript is giving me problems; I will refactor into it later):
CommandComponent.prototype.cleanCommand = function (value) {
value = value.replace(/[^a-z]+/gi, '');
if (0 >= value.indexOf('!') && '!' !== value.substr(0, 1)) {
value = '!' + value;
}
return value;
};
CommandComponent.prototype.isEditingCommand = function (command) {
if (null === this.currentCommand) {
return false;
}
return this.editFormActive && this.currentCommand.id === command.id;
};
// These are not used by the template shown, but they set values used in the functions.
CommandComponent.prototype.editCommand = function (command) {
this.editFormActive = true;
this.currentCommand = command;
};
CommandComponent.prototype.cancelEditCommand = function () {
this.editFormActive = false;
this.currentCommand = null;
};
Environment:
What did I do incorrectly? Let me know if more info is needed, thank you!
Upvotes: 0
Views: 146
Reputation: 16540
I am not sure I understood your issue correctly. But, I only see one problem that could cause some binding issues.
In this line:
<input type="text" class="form-control" placeholder="!command" required [(ngModel)]="cmd.command" (ngModelChange)="cmd.command=cleanCommand($event)" ngControl="cmd" #cmd="ngForm">
You redefined the local variable cmd
. The first one, in the *ngFor="#cmd of commands"
. The other one #cmd="ngForm"
. So, the binding to cmd.command
will be to cmd
the ngForm
not the #cmd of commands
. In other words, You have added a new property command
to ngForm
.
This will explain the circular reference issue because ngForm
is of type NgFormName
which has a _parent
reference.
Upvotes: 2