admin管理员组

文章数量:1316019

I have a page which allows a user to update the colour of a car. There are two api calls, one to bring back the car json object and one to fill a drop down list of colours.

My issue is that Angular 2 appears to do model binding via reference and not value. This means that although the colour 'green' might be set on the car, the color 'green' will not be selected in the drop down list even when it matches as that object has e from a different api call.

Here the select list is bound to the 'colour' property of car.

<div>
    <label>Colour</label> 
    <div>
        <select [(ngModel)]="car.colour">     
            <option *ngFor="let x of colours" [ngValue]="x">{{x.name}}</option>
        </select> 
    </div>
</div>

When I set up the model in the back-end, if I set the color of the car to have the same value object (in this case green), the drop down is not selected. However when I set it using the same instance from the list of values used to bind the list it is selected as expected.

  ngOnInit(): void {

        this.colours = Array<Colour>();
        this.colours.push(new Colour(-1, 'Please select'));
        this.colours.push(new Colour(1, 'Green'));
        this.colours.push(new Colour(2, 'Pink'));

        this.car = new Car();
        //this.car.colour = this.colours[1]; // Works
        this.car.colour = new Colour(1, 'Green');  // Fails    
    }

Here is a plunker showing the issue. Simply switch between these to lines to illustrate the issue.

this.car.colour = this.colours[1]; // Works

this.car.colour = new Colour(1, 'Green'); // Fails

How can I get angular to pare objects by value not reference when binding in this way?

Regards

Steve

Update

I solved in in my use case by setting the models 'superPower' property to the matching item in the list used to populate the dropdown list.

setupUpdate(id: number): void {

    this.pageMode = PageMode.Update;
    this.submitButtonText = "Update";

    this.httpService.get<Hero>(this.appSettings.ApiEndPoint + 'hero/' + this.routeParams.get('id')).subscribe(response => { 
        this.hero = response;             

        this.httpService.get<SuperPower[]>(this.appSettings.ApiEndPoint + 'superPower/').subscribe(response => {
            this.superPowers = response;   
            this.hero.superPower = this.superPowers.filter(x => x.id == this.hero.superPower.id)[0];
        });
    });
}

I have a page which allows a user to update the colour of a car. There are two api calls, one to bring back the car json object and one to fill a drop down list of colours.

My issue is that Angular 2 appears to do model binding via reference and not value. This means that although the colour 'green' might be set on the car, the color 'green' will not be selected in the drop down list even when it matches as that object has e from a different api call.

Here the select list is bound to the 'colour' property of car.

<div>
    <label>Colour</label> 
    <div>
        <select [(ngModel)]="car.colour">     
            <option *ngFor="let x of colours" [ngValue]="x">{{x.name}}</option>
        </select> 
    </div>
</div>

When I set up the model in the back-end, if I set the color of the car to have the same value object (in this case green), the drop down is not selected. However when I set it using the same instance from the list of values used to bind the list it is selected as expected.

  ngOnInit(): void {

        this.colours = Array<Colour>();
        this.colours.push(new Colour(-1, 'Please select'));
        this.colours.push(new Colour(1, 'Green'));
        this.colours.push(new Colour(2, 'Pink'));

        this.car = new Car();
        //this.car.colour = this.colours[1]; // Works
        this.car.colour = new Colour(1, 'Green');  // Fails    
    }

Here is a plunker showing the issue. Simply switch between these to lines to illustrate the issue.

this.car.colour = this.colours[1]; // Works

this.car.colour = new Colour(1, 'Green'); // Fails

https://plnkr.co/edit/m3xBf8Hq9MnKiaZrjAaI?p=preview

How can I get angular to pare objects by value not reference when binding in this way?

Regards

Steve

Update

I solved in in my use case by setting the models 'superPower' property to the matching item in the list used to populate the dropdown list.

setupUpdate(id: number): void {

    this.pageMode = PageMode.Update;
    this.submitButtonText = "Update";

    this.httpService.get<Hero>(this.appSettings.ApiEndPoint + 'hero/' + this.routeParams.get('id')).subscribe(response => { 
        this.hero = response;             

        this.httpService.get<SuperPower[]>(this.appSettings.ApiEndPoint + 'superPower/').subscribe(response => {
            this.superPowers = response;   
            this.hero.superPower = this.superPowers.filter(x => x.id == this.hero.superPower.id)[0];
        });
    });
}
Share Improve this question edited Jul 12, 2016 at 16:55 CountZero asked Jun 24, 2016 at 16:37 CountZeroCountZero 6,3993 gold badges48 silver badges59 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

That's as designed. Angular2 only pares the object reference, not properties of an object.

You can bind to primitive values then pairson works as you expect

    <select [(ngModel)]="car.colour.name">     
        <option *ngFor="let x of colours" [value]="x.name">{{x.name}}</option>
    </select> 

assuming that Color has a property name that contains the string Green.

You can also do the pairson yourself by looking up car.colour in colours and setting car.colour to the Colour instance from colours that represents the same colour.

You can use the following

<select [(ngModel)]="car.colour.name" (ngModelChange)="someFunction($event)" >     
    <option *ngFor="let x of colours" [value]="x.name">{{x.name}}</option>
</select> 

When selected value would be updated, you will handle this in someFunction

本文标签: javascriptDropdown listmodel binding by valueangular 2Stack Overflow