Угловой 4 - использование объектов для значений параметров в списке выбора

Я знаю, что схожие вопросы были заданы, но я не нашел ни одного хорошего ответа. Я хочу создать список выбора в угловой форме, где значение для каждой опции является объектом. Кроме того, я НЕ хочу использовать двухстороннюю привязку данных. например, если мой компонент имеет следующие поля:

    lUsers: any[] = [
        { Name: 'Billy Williams', Gender: 'male' },
        { Name: 'Sally Ride', Gender: 'female'}
        ];
    curUser: any;

Я бы хотел, чтобы мой HTML-шаблон содержал следующее:

    <select #selectElem (change)="setNewUser(selectElem.value)">
        <option *ngFor="let user of lUsers" [ngValue]="user">
            {{user.Name}}
        </option>
    </select>

Однако с помощью этого кода моя функция setNewUser() получает содержимое выбранного поля имени пользователя. Почему он выбирает эту конкретную область, я понятия не имею. Я ожидаю, что он получит "значение" выбранного параметра, который я специально установил для пользовательского объекта.

Обратите внимание, что я использовал ngValue вместо значения в опции. Это было по предложению других на SO. Если я использую значение вместо этого, то происходит то, что объект преобразуется в строку "[Объект объекта]", что и получает setNewUser(), что бесполезно.

FYI, я работаю над Windows 10, используя угловой 4.0.0 с @angular/cli 1.1.2. Вот метод setNewUser():

    setNewUser(user: User): void {

    console.log(user);
    this.curUser = user;
    } // setNewUser()

Я определяю, что именно передается ему как в моем протоколе, так и в том числе в шаблоне: <pre>{{curUser}}</pre>

Ответы

Ответ 1

В настоящее время я использую [ngValue] и он хранит объекты просто отлично.

Объяснение того, почему вы столкнулись с проблемами, использующими (change) вместо (ngModelChange) можно найти в этом вопросе

Итак, поскольку вы уже использовали [ngValue], вы, вероятно, захотите сделать что-то вроде этого, где вы будете использовать только один способ привязки, чтобы иметь возможность использовать директиву ngModelChange:

<select (ngModelChange)="setNewUser($event)" (ngModel)="lUsers">
        <option *ngFor="let user of lUsers" [ngValue]="user">
            {{user.Name}}
        </option>
    </select>

И ваш ts файл захватит событие и получит объект User без необходимости отслеживать его по id, в основном повторное использование старого метода будет достаточно хорошим:

setNewUser(user: User): void {
    console.log(user);
    this.curUser = user;
    }

Ответ 2

Поскольку атрибут value тега option не может хранить целый объект, мы создадим новый id свойства в массиве lUsers чтобы отслеживать выбранный элемент.

HTML:

<select #selectElem (change)="setNewUser(selectElem.value)">
    <option *ngFor="let user of lUsers" [value]="user.id">
        {{user.Name}}
    </option>
</select>

Это передаст уникальный id нашей функции setNewUser при изменении.

В вашем компоненте:

...

lUsers: any[] = [
    { id: 1, Name: 'Billy Williams', Gender: 'male' },
    { id: 2, Name: 'Sally Ride', Gender: 'female'}
];
curUser: any = this.lUsers[0]; // first will be selected by default by browser

...

setNewUser(id: any): void {
    console.log(id);
    // Match the selected ID with the ID in array
    this.curUser = this.lUsers.filter(value => value.id === parseInt(id));
    console.log(this.curUser);
}

Вот демоверсия plnkr из приведенного выше кода. Откройте инструменты разработчика, чтобы просмотреть журналы консоли.