从组件内更新 属性 绑定

Update property binding from within a component

我在另一个(父)组件中使用了一个简单的自定义下拉组件。

一切都很好。但是每当我通过选择另一个选项来更改下拉列表的值时,绑定到组件的值就永远不会更新。

我的组件如下所示:

@Component({
  selector: 'dropdown',
  templateUrl: './dropdown.component.html',
  styleUrls: ['./dropdown.component.scss']
})
export class DropdownComponent implements OnInit {

  @Input()
  userId: number;

  ngOnInit() {
    if(!this.userId) {
      this.userId = 1;
    }
  }
}

和 html:

<select [ngClass]="[sizeClass]" [(ngModel)]="userId">
  <option value="1">val 1</option>
  <option value="2">val 2</option>
</select>

我在父组件中使用它是这样的(app.component.html):

<dropdown [(userId)]="appUserId"></dropdown>
<br><br>
<button (click)="saveData()">Save</button>

并且在 app.component.ts 中:

export class AppComponent implements OnInit  {
  appUserId: number;

  ngOnInit() {
    this.appUserId = 1;
  }

  saveData(): void {
    // I expect appUserId to be changed, because I picked another value from the dropdown
    alert('selected userid = ' + this.appUserId);
  }
}

当我点击保存按钮时,它会显示我的 属性 永远不会更新。

演示应用程序

我这里有一个演示:

https://stackblitz.com/edit/angular-c3ew8a?file=src/app/dropdown/dropdown.component.html

重现:

我希望看到显示文本 selected userid = 2 的警报。但它显示:selected userid = 1。它从未更新 userId 属性.

我在 Angular 中必须做什么才能完成这项工作?

问题是您尝试在应用组件和下拉组件之间使用 two-ways data binding,就像在组件和它自己的模板之间使用它一样。

可以使用两种方式在组件之间进行数据绑定,但为了做到这一点,您必须为子组件提供一个 Input()(就像您所做的那样),并从您的子组件发出一个同名事件作为您的输入 + 'Change' 后缀。此事件应包含新值。

我 fork 你的 stackblitz 所以你可以看到你想要的工作示例。

@Component({
  selector: 'dropdown',
  templateUrl: './dropdown.component.html',
  styleUrls: ['./dropdown.component.scss']
})
export class DropdownComponent implements OnInit {

  @Input()
  userId: number;

  @Output() // Emit event with the same name of the input and 'Change' suffix 
  userIdChange = new EventEmitter();

  ngOnInit() {
    if(!this.userId) {
      this.userId = 1;
    }
  }
}
<select [ngClass]="[sizeClass]" [value]="userId" (change)="userIdChange.emit($event.target.value)"> <!-- $event.target is the target of the change event with is the select element) -->
  <option value="1">val 1</option>
  <option value="2">val 2</option>
</select>

Reference 来自 Angular 文档