2

I have an (Angular 2) root component called AppComponent that uses another component called Subcomp. App passes an @Input() parameter to Sub. Sub uses this variable for one-way binding in an input field.

Now I...

  1. Set the parameter's value to some initial value ("start"); this is displayed in the input field as expected.
  2. Change the text in the input field to something else.
  3. Click on a button to programmatically reset the value in the AppComponent back to "start".

I then expect the input field to also reset to "start", but instead it keeps displaying the changed text from step 2. Is that correct behavior?

The code:

class Todo {
    constructor(public title: string) {}
}

@Component({
    selector: 'subcomp',
    directives: [FORM_DIRECTIVES],
    template: `New Title: <input type="text" [ngModel]="subtodo.title">`
})
export class Subcomp {
    @Input() subtodo: Todo;
}

@Component({
    selector: 'my-app',
    directives: [Subcomp],
    template: `To do: {{todo.title}}<br/>
               <subcomp [subtodo]="todo"></subcomp><br/>
               <button (click)="update()">Update</button>`
})
export class AppComponent {

    todo: Todo = new Todo('start');

    update() {
        this.todo = new Todo('start');
    }

}

1 Answer 1

1

Yes it is correct behavior.

Because you are only using one-way databinding in Subcomp, the value of todo.title does not change when you change text in the input field.

When update() is called, a new Todo object is created, but the value of todo.title is start, so when Angular change detection looks at [ngModel]="subtodo.title", it sees no change – the old value of subtodo.title is start as is the current value. Angular change detection compares primitive types (number, string, boolean) by value.

To prove it, try this:

update() {
    this.todo = new Todo('start' + new Date());
}

or try this:

<input type="text" [(ngModel)]="subtodo.title">
Sign up to request clarification or add additional context in comments.

4 Comments

OK, this makes sense even if it seems counter-intuitive when using it. Thanks!
When the new Todo('xxx') created by update() has a different value it still doesn't update the input. Also not when instead Todo ngModel is bound to a simple string field. To me it still looks like a bug.
@GünterZöchbauer, this plunker shows that new Todo('start' + new Date()) does update the input. (Using Beta.0, if that matters. I haven't moved off that yet, as it seems to have fewer bugs.)
Right, you mentioned it already in your answer. Thanks for the Plunker. Seems I made a mistake when I tried. Now it also works in Dart this way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.