简体   繁体   English

如何避免子窗体在AngularJS中使外部窗体$ dirty出现?

[英]How to avoid a subform to make outer form $dirty in AngularJS?

Forms in AngularJS sometimes can become a bit ugly. AngularJS中的表单有时可能会变得有些丑陋。 That's my case. 那是我的情况。 I have seemingly simple structure of three forms. 我看似具有三种形式的简单结构。 Two of them should be related to each other, while third should be completely separate. 其中两个应相互关联,而第三个应完全分开。

<form name="foo">
   <div ng-repeat="f in foo.list">
      <custom-component ng-form="foo['f_'+$index+'_something']"></custom-component>
   </div>
</form>

Above is main form. 以上是主要形式。 It binds some part of itself to custom component. 它将自身的某些部分绑定到自定义组件。

The component on the other hand has two forms inside: 另一方面,组件内部有两种形式:

<div ng-form="$ctrl.form">
   <!--foo-->
</div>
<some-popup>
   <div ng-form="$ctrl.popupForm">
      <!--foo-->
   </div >
</some-popup>

The problem is that popupForm is somehow automatically bound with other forms. 问题是popupForm会以某种方式自动与其他表单绑定。 The result is far from expectations. 结果远非预期。 When I modify popupForm it makes item on foo form dirty. 当我修改popupForm它会使foo表单上的项目变脏。 Moreover if some field on popupForm doesn't meet validation criteria, and popup is closed then error is propagated to the foo form's item. 此外,如果popupForm上的某些字段不符合验证条件,并且关闭了弹出窗口,则错误将传播到foo表单的项目。 The latest problem can be solved with ng-if directive used to "remove" popupForm from DOM when popup is hidden, but it still not complete solution. 最新的问题可以通过ng-if指令来解决, ng-if指令用于在隐藏弹出窗口时从DOM中“删除” popupForm ,但它仍不是完整的解决方案。

It there any way to make a form ( popupForm of the example) completely separate from other? 是否有任何方法可以使表单(示例的popupForm )与其他表单完全分开? Can I prevent nesting forms somehow? 我可以以某种方式防止嵌套表格吗?

The $removeControl method can be used to remove a child form from its parent. $removeControl方法可用于从其父级中删除子级表单。

$removeControl(control); $ removeControl(control);

Deregister a control from the form. 从表单中注销控件。

Input elements using ngModelController do this automatically when they are destroyed. 使用ngModelController的输入元素在销毁时会自动执行。

— AngularJS Form Controller API Reference ( $removeControl ) — AngularJS Form Controller API参考( $removeControl

Problem is more complicated. 问题更加复杂。 As was mentioned before HTML standard doesn't allow <form> nesting - https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form - Permitted content . 如前所述,HTML标准不允许<form>嵌套-https: //developer.mozilla.org/en-US/docs/Web/HTML/Element/form- 允许的内容

If you are not plan to cross-validate this <div ng-form="$ctrl.popupForm"> with <div ng-form="$ctrl.form"> usually this should be done by attach/append popup element do different DOM element. 如果您不打算将此<div ng-form="$ctrl.popupForm"><div ng-form="$ctrl.form">进行交叉验证,通常应通过附加/附加popup元素来完成此操作DOM元素。

For example angular-ui components Bootstrap Modal https://angular-ui.github.io/bootstrap/ have property called appendTo . 例如angular-ui组件Bootstrap Modal https://angular-ui.github.io/bootstrap/具有名为appendTo属性。 This should solve <form> inheritance issue if you are using modals like Bootrstrap or Material Design http://mseemann.io/frontend/2016/10/10/angular-2-mdl-mdl-dialog-advanced-configuration.html . 如果您正在使用Bootrstrap或Material Design之类的模式,这应该可以解决<form>继承问题http://mseemann.io/frontend/2016/10/10/angular-2-mdl-mdl-dialog-advanced-configuration.html

More hacky alternatives involve creating custom directive and attach element using https://docs.angularjs.org/api/ng/service/ $compile compile functions. 更多骇人听闻的选择包括使用https://docs.angularjs.org/api/ng/service/ $ compile compile函数创建自定义directive和附加元素。 Angular directives - when and how to use compile, controller, pre-link and post-link Angular指令-何时以及如何使用编译,控制器,预链接和后链接

If you plan to have cross-validation, this should be solved with service / provider for communication and testability. 如果您打算进行交叉验证,则应与service / provider进行沟通和可测试性解决。

Standard HTML doesn't allow nesting forms. 标准HTML不允许嵌套表格。 Have a look at ngForm . 看看ngForm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM