gpt4 book ai didi

angularjs - 如何在 AngularJS 表单中嵌套 Angular 2+ 表单?

转载 作者:行者123 更新时间:2023-12-04 17:29:03 25 4
gpt4 key购买 nike

我正在努力将一个大型 AngularJS 应用程序升级到 Angular 5+。这意味着在混合 AngularJS 应用程序中使用新的 Angular 5 组件。在许多情况下,表单嵌套在其他表单中。旧的 AngularJS 代码有这样的父表单:

export default function PersonDirective() {
return {
restrict: "E",
template: `
<div ng-form="personForm">
<input type="text" name="surname" ng-model="person.surname" ng-required="true">
<address-form address="person.homeAddress"></address-form>
</div>`,
replace: true,
scope: {
person: "="
}
};
}

和子表类似:

export default function AddressDirective() {
return {
restrict: "E",
template: `
<div ng-form="addressForm">
<input type="text" name="firstLine" ng-model="address.firstLine" ng-required="true">
<input type="text" name="city" ng-model="address.city" ng-required="true">
</div>`,
replace: true,
scope: {
address: "="
}
};
}

这导致 PersonDirective 的 FormController 具有地址表单,作为一个名为 addressForm 的嵌套 FormController 字段。子表单中的验证错误会影响父表单的有效性。

我已将地址表单转换为 Angular 5 组件,用标准 HTML 替换 AngularJS ng-formng-required 指令:

@Component({
selector: 'address-form',
template: `
<div>
<form #addressForm="ngForm">
<input type="text" name="firstLine" [(ngModel)]="address.firstLine" required>
<input type="text" name="city" [(ngModel)]="address.city" required>
</div>`
})
export class AddressFormComponent {
@Input() address: any;
}

新组件在 index.ts 中降级以用于 AngularJS:

angular.module('common')
.directive("ng2AddressForm", downgradeComponent({component: AddressFormComponent}));

并修改 PersonDirective 模板以使用新组件:

<div ng-form="personForm">
<input type="text" name="surname" ng-model="person.surname" ng-required="true">
<ng2-address-form address="person.homeAddress"></ng2-address-form>
</div>

新组件按预期显示和验证。问题是它不再作为一个字段出现在父表单中,它的有效性和状态也不再传播到父表单。一次转换所有形式是不可能的。谁能提出解决方案?

最佳答案

我发现的最佳解决方案是创建一个实现 ControlValueAccessor 和 Validator 的子组件。 ControlValueAccessor 允许组件绑定(bind)到任意对象(我上面示例中的地址),在新的 Angular 2+ 模板中使用 [(ngModel)] 并在旧的 AngularJS 模板中使用 ng-model。

在新模板中,子组件的有效性状态会自动影响父表单的有效性。在 AngularJS 中,我不得不使用事件处理程序向父级报告子级状态。所以关系看起来像这样:

在 AngularJS 父表单模板中:

<ng2-address-form 
ng-model="myCtrl.person.homeAddress"
(status)="myCtrl.onAddressStatus($event)">
</ng2-address-form>

在 Angular 2+ 组件中:

export class AddressFormComponent implements ControlValueAccessor, Validator   {
@Output("status") statusEvent = new EventEmitter<ValidationErrors | null>();
addressForm: FormGroup;
...
this.addressForm.statusChanges.subscribe(s => this.statusEvent.emit(this.validate(null)));
...
validate(c: AbstractControl): ValidationErrors | null {
// validate the form
}

我发现使用响应式表单更容易,因为它使组件逻辑可以直接访问表单控件。

关于angularjs - 如何在 AngularJS 表单中嵌套 Angular 2+ 表单?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61386813/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com