Detach then append AngularJS form change validity status

我怕爱的太早我们不能终老 提交于 2019-12-05 13:25:13

The problem happens because input directive removes itself from the form controls when the element is removed from DOM. As it doesn't link your ngModel and form controller again, your input is not being considered by the form anymore.

You basically have two three options:

  • change element visibility instead of removing it
  • (prefer the one below) exposing a "relink" function that would re-add it to the original form
  • triggering a custom event on all controls so they can relink theirselves

Changing element visibility means you will have unnecessary DOM elements in DOMTree. This is not quite bad, as you are keeping a reference to the $compile element anyway, so it will yet participate the $digest cycles and "DOM" modifications.

(After thinking for a while, the new solution is slightly better than this one, so don't expose a relinking function) Exposing a relink function is quite weird (although functional) and this is not the most reliable of the solutions. One way to achieve it consists in requiring form controller (require: ['ngModel', '^?form']) and binding a relinking function to the element's data:

element.data('relink', function(){
  formCtrl && formCtrl.$addControl(ngModelCtrl);
});

And when you add the element to the screen again, you gonna have to call all your controls relink function:

$('.controls').data('relink')();

See a example here.

It's not quite reliable, but might work for your case.

Triggering a custom event is pretty much the same as the previous, but you would dispatch a custom event on all elements that should relink theirselves. This is way more organized, but still not quite reliable, because the form and other links might also have been broken (again, should sufice your case). Basically listen to the custom event on your directive:

element.bind('$append', function(){
  formCtrl && formCtrl.$addControl(ngModelCtrl);
});

And after changing to the form, just trigger the custom event on all controls:

$('.control').triggerHandler('$append');

The reason why this one is better is that the directive still decides when to relink the component, and the event is kind of "generic". Here is a working plunker.

As a last effort, you could override jQuery.fn.append and trigger the custom event on all element children recursively (this is what Angular does when removing elements). This is the most organized, but it would impact yoour performance on ALL append calls.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!