diff --git a/src/ngMessages/messages.js b/src/ngMessages/messages.js index 14ffe00506b0..20edf80fa1c0 100644 --- a/src/ngMessages/messages.js +++ b/src/ngMessages/messages.js @@ -325,6 +325,9 @@ angular.module('ngMessages', []) controller: ['$element', '$scope', '$attrs', function($element, $scope, $attrs) { var ctrl = this; var latestKey = 0; + var nextAttachId = 0; + + this.getAttachId = function getAttachId() { return nextAttachId++; }; var messages = this.messages = {}; var renderLater, cachedCollection; @@ -636,11 +639,15 @@ function ngMessageDirectiveFactory(restrict) { $animate.enter(elm, null, element); currentElement = elm; + // Each time we attach this node to a message we get a new id that we can match + // when we are destroying the node later. + var $$attachId = currentElement.$$attachId = ngMessagesCtrl.getAttachId(); + // in the event that the parent element is destroyed // by any other structural directive then it's time // to deregister the message from the controller currentElement.on('$destroy', function() { - if (currentElement) { + if (currentElement && currentElement.$$attachId === $$attachId) { ngMessagesCtrl.deregister(commentNode); messageCtrl.detach(); } diff --git a/test/ngMessages/messagesSpec.js b/test/ngMessages/messagesSpec.js index 037175031ded..3d4f1100f06c 100644 --- a/test/ngMessages/messagesSpec.js +++ b/test/ngMessages/messagesSpec.js @@ -372,6 +372,50 @@ describe('ngMessages', function() { expect(trim(element.text())).toEqual("Enter something"); })); + // issue #12856 + it('should only detach the message object that is associated with the message node being removed', + inject(function($rootScope, $compile, $animate) { + + // We are going to spy on the `leave` method to give us control over + // when the element is actually removed + spyOn($animate, 'leave'); + + // Create a basic ng-messages set up + element = $compile('