ChatGPT解决这个技术问题 Extra ChatGPT

如何在 Angular 2 的“选择”中获得新的选择?

我正在使用 Angular 2(TypeScript)。

我想对新选择做点什么,但我在 onChange() 中得到的始终是最后一个选择。我怎样才能获得新的选择?

<select [(ngModel)]="selectedDevice" (change)="onChange($event)">
   <option *ngFor="#i of devices">{{i}}</option>
</select>
onChange($event) {
    console.log(this.selectedDevice);
    // I want to do something here with the new selectedDevice, but what I
    // get here is always the last selection, not the one I just selected.
}

M
Mark Rajcok

如果您不需要双向数据绑定:

<select (change)="onChange($event.target.value)">
    <option *ngFor="let i of devices">{{i}}</option>
</select>

onChange(deviceValue) {
    console.log(deviceValue);
}

对于双向数据绑定,将事件绑定和属性绑定分开:

<select [ngModel]="selectedDevice" (ngModelChange)="onChange($event)" name="sel2">
    <option [value]="i" *ngFor="let i of devices">{{i}}</option>
</select>
export class AppComponent {
  devices = 'one two three'.split(' ');
  selectedDevice = 'two';
  onChange(newValue) {
    console.log(newValue);
    this.selectedDevice = newValue;
    // ... do other stuff here ...
}

如果 devices 是对象数组,则绑定到 ngValue 而不是 value

<select [ngModel]="selectedDeviceObj" (ngModelChange)="onChangeObj($event)" name="sel3">
  <option [ngValue]="i" *ngFor="let i of deviceObjects">{{i.name}}</option>
</select>
{{selectedDeviceObj | json}}
export class AppComponent {
  deviceObjects = [{name: 1}, {name: 2}, {name: 3}];
  selectedDeviceObj = this.deviceObjects[1];
  onChangeObj(newObj) {
    console.log(newObj);
    this.selectedDeviceObj = newObj;
    // ... do other stuff here ...
  }
}

Plunker - 不使用 <form>
Plunker - 使用 <form> 并使用新的表单 API


anwere 是对的,但是 ngModel 在这里的作用是什么,我仍然很困惑,你能解释一下吗?
@PardeepJain,使用与 NgModel 的双向数据绑定导致 Angular 1)在用户选择不同的项目时自动更新 selectedDevice,2)如果我们设置 selectedDevice 的值,NgModel 将自动更新视图。由于我们还希望收到更改通知,因此我添加了 (change) 事件绑定。我们不应该这样做......我们应该能够将双向数据绑定分解为 [ngModel]="selectedDevice" and (ngModelChange)="onChange($event)",但正如我发现的那样,每次选择列表以这种方式更改都会调用 onChange() 两次.
@HongboMiao,特殊的 $event 变量/符号是 Angular 模板语句具有的“语句上下文”的一部分。相反,如果我写的是 (ngModelChange)="onChange('abc')",那么 newValue 将得到字符串 abc。这只是普通的 JavaScript 函数调用。
@HongboMiao,如果您有一组对象,请使用 [ngValue]。如果您有一个原始类型数组(字符串、布尔值、整数),请使用 [value]。
$event.target.value 类型“EventTarget”上不存在属性“值”??你能为打字稿4提供建议吗
B
Brocco

您可以通过在选择标记 #device 上创建一个引用变量并将其传递给更改处理程序 onChange($event, device.value) 将值传递回组件应该具有新值

<select [(ng-model)]="selectedDevice" #device (change)="onChange($event, device.value)">
    <option *ng-for="#i of devices">{{i}}</option>
</select>

onChange($event, deviceValue) {
    console.log(deviceValue);
}

您在这里没有绑定到 ngModel,而是绑定到了一个名为 device 的新变量。
[(ngModel)] 的卷在这里
R
Rusty Rob

只需使用 [ngValue] 而不是 [value]!

export class Organisation {
  description: string;
  id: string;
  name: string;
}
export class ScheduleComponent implements OnInit {
  selectedOrg: Organisation;
  orgs: Organisation[] = [];

  constructor(private organisationService: OrganisationService) {}

  get selectedOrgMod() {
    return this.selectedOrg;
  }

  set selectedOrgMod(value) {
    this.selectedOrg = value;
  }
}


<div class="form-group">
      <label for="organisation">Organisation
      <select id="organisation" class="form-control" [(ngModel)]="selectedOrgMod" required>
        <option *ngFor="let org of orgs" [ngValue]="org">{{org.name}}</option>
      </select>
      </label>
</div>

这对我有帮助。不确定我的情况是否略有不同,但对我来说 (change)="selectOrg(selectedOrg)" 使用当前/上一个选择调用函数 selectOrg,而不是新选择的选项。我想通了,我什至不需要 (change) 位。
很好的定位。是的,这是(更改)通过旧模型的奇怪行为。我认为这就像 ng-change 也许这是 angular2 中的一个错误。我已将其更新为使用 get 和 set 方法。这样,在 set selectedOrgMod(value) 方法中,我可以知道组织已更改并更新我的组织团队列表。
j
jarisky

我在 https://angular.io/docs/ts/latest/guide/forms.html 做 Angular 2 表单教程(TypeScript 版本)时遇到了这个问题

选择/选项块不允许通过选择其中一个选项来更改选择的值。

做 Mark Rajcok 建议的工作,虽然我想知道我在原始教程中是否遗漏了一些东西,或者是否有更新。在任何情况下,添加

onChange(newVal) {
    this.model.power = newVal;
}

到 HeroFormComponent 类中的 hero-form.component.ts

(change)="onChange($event.target.value)"

<select> 元素中的 hero-form.component.html 使其工作


v
valentine

在角度 6 及以上使用 selectionChange。示例 (selectionChange)= onChange($event.value)


我没有使用反应形式的方法。我只需要选择的值来触发基于该单个值的服务调用..上述方法帮助了我。
从 Angular 9+ 开始,这不再有效。 $event.value 不再可用
A
Abd Abughazaleh

我有同样的问题,我使用下面的代码解决了:

(change)="onChange($event.target.value)"

这在较新版本的 Angular 中不起作用
B
B.Habibzadeh

在 Angular 8 中,您可以像这样简单地使用“selectionChange”:

 <mat-select  [(value)]="selectedData" (selectionChange)="onChange()" >
  <mat-option *ngFor="let i of data" [value]="i.ItemID">
  {{i.ItemName}}
  </mat-option>
 </mat-select>

这是一个物质事件
k
kravits88

另一种选择是将对象作为字符串存储在值中:

<select [ngModel]="selectedDevice | json" (ngModelChange)="onChange($event)">
    <option [value]="i | json" *ngFor="let i of devices">{{i}}</option>
</select>

零件:

onChange(val) {
    this.selectedDevice = JSON.parse(val);
}

这是我可以获得两种方式绑定工作以在页面加载时设置选择值的唯一方法。这是因为填充选择框的列表与我的选择绑定到的对象并不完全相同,它必须是相同的对象,而不仅仅是相同的属性值。


7
7guyo

角度 7/8

从 Angular 6 开始,在 Angular 7+ 中,ngModel 输入属性与反应形式指令的使用已被弃用并完全删除。 Read official doc here.

使用反应式表单方法,您可以获取/设置选定的数据;

      //in your template
 <select formControlName="person" (change)="onChange($event)"class="form-control">
    <option [value]="null" disabled>Choose person</option>
      <option *ngFor="let person of persons" [value]="person"> 
        {{person.name}}
    </option>
 </select> 


 //in your ts
 onChange($event) {
    let person = this.peopleForm.get("person").value
    console.log("selected person--->", person);
    // this.peopleForm.get("person").setValue(person.id);
  }

是否还有其他两种方式绑定,如 NgModel 不被弃用?
如果您不使用该值,为什么您的 ts 函数中有 $event 参数?
J
Jérémie Bertrand
<mat-form-field>
<mat-select placeholder="Vacancies" [(ngModel)]="vacanciesSpinnerSelectedItem.code" (ngModelChange)="spinnerClick1($event)"
    [ngModelOptions]="{standalone: true}" required>
    <mat-option *ngFor="let spinnerValue of vacanciesSpinnerValues" [value]="spinnerValue?.code">{{spinnerValue.description}}</mat-option>
</mat-select>

我将其用于角度材质下拉列表。工作正常


A
Alexander

我尝试了所有建议,但对我没有任何作用。

想象一下这种情况:您需要一个 2 路绑定,并且您有一个包含 NUMBER 值的查找,并且您希望使用此查找中的值填充您的 SELECT 并突出显示所选的选项。

使用 [value] 或 (ngModelChange) 是不行的,因为在用户启动更改后您将无法选择所选选项: [value] 将所有内容视为字符串,至于 (ngModelChange) - 它显然不应该在用户启动更改时使用,因此会破坏正确的选择。使用 [ngModel] 保证接收到的 VALUE 的固定格式为 INDEX: VALUE 并且很容易相应地解析它,但是再一次 - 它破坏了选定的选项。

因此,我们使用 [ngValue](它将处理正确的类型)、(更改)和... [value],它保证处理程序接收 VALUE,而不是 DISPLAYED VALUE 或 INDEX:VALUE :) 下面是我的工作笨拙解决方案:

  <select
    class="browser-default custom-select"
    (change)="onEdit($event.target.value)"
  >
    <option [value]="">{{
      '::Licences:SelectLicence' | abpLocalization
    }}</option>
    <ng-container *ngIf="licencesLookupData$ | async">
      <option
        *ngFor="let l of licencesLookupData$ | async"
        [ngValue]="l.id"
        [value]="l.id"
        [selected]="l.id == selected.id"
      >
        {{ l.id }} &nbsp;&nbsp; {{ l.displayName | defaultValue }}
      </option>
    </ng-container>
  </select>

  onEdit(idString: string) {
    const id = Number(idString);
    if (isNaN(id)) {
      this.onAdd();
      return;
    }
    this.licencesLoading = true;
    this.licencesService
      .getById(id)
      .pipe(finalize(() => (this.licencesLoading = false)), takeUntil(this.destroy))
      .subscribe((state: Licences.LicenceWithFlatProperties) => {
        this.selected = state;
        this.buildForm();
        this.get();
      });
  }

s
skid

最新的 ionic 3.2.0 已修改 (change) 为 (ionChange)

例如:HTML

<ion-select (ionChange)="function($event)"> <ion-option>1<ion-option>
</ion-select>

TS

function($event){
// this gives the selected element
 console.log($event);

}

v
valentine

在 Angular 5 中,我采用了以下方式。获取对象 $event.value 而不是 $event.target.value

<mat-form-field color="warn">
   <mat-select (ngModelChange)="onChangeTown($event)" class="form-width" formControlName="branch" [(ngModel)]="branch" placeholder="Enter branch">
     <mat-option *ngFor="let branch of branchs" [value]="branch.value">
                  {{ branch.name }}
     </mat-option>
   </mat-select>
</mat-form-field>

onChangeTown(event): void {
  const selectedTown = event;
  console.log('selectedTown: ', selectedTown);
}

H
HDJEMAI

从 Angular 7 开始,由于 ngModel 已被弃用,我们可以简单地使用控件以反应方式非常轻松地获取新的选定值。

例子:

<form [formGroup]="frmMyForm">
  <select class="form-control" formControlName="fieldCtrl">
    <option value=""></option>
    <option value="val1">label val 1</option>
    <option value="val2">label val 2</option>
    <option value="val3">label val 3</option>
  </select>
</form>
this.frmMyForm.get('fieldCtrl').valueChanges.subscribe( value => {
  this.selectedValue = value;
});

通过使用这种完全反应式的方式,我们可以更轻松地将较旧的 Angular 应用程序版本升级到较新的版本。


t
tinystone

如果您不需要双向数据绑定:

<select (change)="updateSorting($event)">
  <option disabled selected>Sorting</option>
  <option value="pointDes">pointDes</option>
  <option value="timeDes">timeDes</option>
  <option value="timeAsc">timeAsc</option>
  <option value="pointAsc">pointAsc</option>
</select>
updateSorting(e: any) {
  // console.log((e.target as HTMLSelectElement)?.value); // also work
  console.log(e.target.value);
}