marcorinck / jsf-updates-angular

Update angularJS after JSF Ajax requests are complete
5 stars 2 forks source link

Input fields: JSF updates of field values are overwritten by ng-model #6

Open stephanrauh opened 9 years ago

stephanrauh commented 9 years ago

Consider a JSF view containing an update="@form". The form contains an input field that's incremented on the server side with each AJAX request. The input field also has an ng-model="myOldValue" directive.

The JSF response updates the value of the input field. Unfortunately, the old value is restored a short time later when the input field is compiled by AngularJS (because ng-model hasn't been updated).

stephanrauh commented 9 years ago

I'm not sure, but the issue may have been caused by moving handleAjaxUpdates from oncomplete to onsuccess (which in turn was necessary because the $injector tends to get lost or inaccessible after destroying scopes).

        jsf.ajax.addOnEvent(function (data) {
            if (data.status === 'begin') {
                requestOngoing = true;
                onCompleteCallbacks = [];
            }
            if (data.status === 'complete') {
            }
            if (data.status === 'success') {
                // todo: handleAjaxUpdates() should be called in the 'complete' branch 
                // - find a way to pass the injector around
                var theInjector=destroyScopes(data.responseXML);
                handleAjaxUpdates(data.responseXML, theInjector);
                requestOngoing = false;
            }
        });
marcorinck commented 9 years ago

Small typo: originally destroyScopes is done in complete phase and handleAjaxUpdates is done in succcess phase. In your code you moved destroyscopes and not handleAjaxUpdates from complete to success phase.

As described in #3 the order when to destroy old scopes and when to let angular know about new elements is very important!

destroyScopes needs to be done in complete phase as only in this phase, JSF hasn't touched the DOM and has NOT updated the nodes with new ones. You NEED to destroy scopes in this phase, as updated DOM nodes don't know anything about angular and vice versa. As angular wouldn't be able to destroy anything this would cause a memory leak.

In success phase the DOM is updated by JSF and angular can do its magic for them.

I assume that your fix to get the injector and this move of destroying scopes in later phase are connected and is causing your problems.