Closed FWennerdahl closed 6 years ago
@FWennerdahl unfortunately, we do not support using the editor inside ng-repeat. The problem is coming from the fact that when the render action happens, the old editor instance is not being destroyed but just removed from the DOM.
I'm sorry, but this doesn't seem to be accurate. At https://github.com/froala/angular-froala/blob/master/src/angular-froala.js#L150 in the $destroy-handler the editor is destroyed. Placing a breakpoint directly after it in the JSFiddle above shows that the editor has been destroyed and the underlying textarea is shown instead.
The issue is seems rather that event listeners are being added anew to the same element
when the editor is destroyed and then reinitialized on blur. Would a viable solution be to prevent the same angular-froala directive instance from binding event listeners more than once?
@FWennerdahl sorry, I was wrong. What it appears to be happening is that the destroy event is triggered twice: once internally by the ng-repeat and then again by the blur event. I think there should be something like this: https://jsfiddle.net/yax8pLp3/2/.
@stefanneculai There's a difference between the $destroy
event (called by AngularJS when the Angular $scope for the directive is destroyed) and the call to initControls.destroy
(which is called in the blur event handler and destroys the Froala editor instance but not the directive).
It's not the initControls.destroy that is called twice, rather the angular $destroy handler, since when reinitializing the editor the same $destroy-handler has been registered twice on the element. I think something like directiveInitialized
would be more accurate:
ctrl.initListeners = function() {
// Still want this to be set up again after re-initialization.
if (ctrl.options.immediateAngularModelUpdate) {
ctrl.froalaElement.on('keyup', function() {
scope.$evalAsync(ctrl.updateModelView);
});
}
if (!ctrl.directiveInitialized) {
element.on('froalaEditor.contentChanged', function() {
scope.$evalAsync(ctrl.updateModelView);
});
element.bind('$destroy', function() {
element.off(ctrl.listeningEvents.join(" "));
element.froalaEditor('destroy');
element = null;
});
ctrl.directiveInitialized = true;
}
};
What do you think?
Expected behavior.
When destroying and reinitializing an editor the event listeners set up in
ctrl.initListeners
should not be added again to the element.Actual behavior.
The event listeners are added again, causing issues for example when the editor is located within an ng-repeat.
Steps to reproduce the problem.
When the model is updated, the ng-repeat will re-render, causing
$destroy
to be called on the angular-froala directive. Since the editor had been reinitialized, two listeners are now registered for the $destroy event and since the listener setselement
tonull
, the second listener will cause the following error:From reading the issue tracker on the Froala WYSIWYG editor, the intended way to bring an editor back to non-initialized state (when using
initOnClick
) is to reinitialize it, see https://github.com/froala/wysiwyg-editor/issues/1822. As such, it's expected that this will work even if the editor is located in an ng-repeat and the model updates externally.OS.
macOS 10.12.6
Browser.
Chrome 63.0.3239.132