Angularjs Multiple Directives Asking For Transclusion when lazy loading

Problem

I'm trying to setup a simple angularjs app using ui.router, ocLazyLoad, Foundation and angular-foundation.

The app is a multi-view app with it's components lazy loaded using ocLazyLoad. I have no problem setting up the views and associated controllers. However, I am having an issue when trying to display a Foundation alert. When I try to view my alerts (route1), I get empty alerts. And the stack trace below.

Why is angular applying the alert directive twice? A plunker is available here: http://goo.gl/lhtD0c

Error: [$compile:multidir] Multiple directives [alert, alert] asking for transclusion on:        
<div class="alert-box" ng-class="(type || &quot;&quot;)" ng-repeat="alert in alerts" type="alert.type" close="closeAlert($index)">
http://errors.angularjs.org/1.2.22/$compile/multidir?p0=alert&p1=alert&p2=t…lerts%22%20type%3D%22alert.type%22%20close%3D%22closeAlert(%24index)%22%3E
at https://code.angularjs.org/1.2.22/angular.js:78:12
at assertNoDuplicate (https://code.angularjs.org/1.2.22/angular.js:6933:15)
at applyDirectivesToNode (https://code.angularjs.org/1.2.22/angular.js:6353:13)
at https://code.angularjs.org/1.2.22/angular.js:6858:37
at https://code.angularjs.org/1.2.22/angular.js:8091:11
at wrappedCallback (https://code.angularjs.org/1.2.22/angular.js:11546:81)
at wrappedCallback (https://code.angularjs.org/1.2.22/angular.js:11546:81)
at https://code.angularjs.org/1.2.22/angular.js:11632:26
at Scope.$eval (https://code.angularjs.org/1.2.22/angular.js:12658:28)
at Scope.$digest (https://code.angularjs.org/1.2.22/angular.js:12470:31)

The body of my index is below:

<body>
    <div>
        <a class="button" ui-sref="route1">Route 1</a>
        <a class="button" ui-sref="route2">Route 2</a>
    </div>

    <div ui-view></div>
</body>

The javascript associated with this page is:

var myapp = angular.module('myapp', ['ui.router', 'oc.lazyLoad', 'mm.foundation'])

myapp.config(function($stateProvider, $urlRouterProvider){

  // For any unmatched url, send to /route2
  $urlRouterProvider.otherwise('/route2')

  $stateProvider
    .state('route1', {
        url: "/route1",
        controller: 'Route1',
        templateUrl: "route1.html",
        resolve: {
            loadCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
                return $ocLazyLoad.load({
                    name: 'myapp',
                    files: ['route1.js']
                })
            }]
        }
    })
    .state('route2', {
        url: "/route2",
        templateUrl: "route2.html"
    })
});

$(function() {
    Foundation.global.namespace = '';
    $(document).foundation();
})

The problems are associated with route1. Here is the route1 template.

<div ng-controller="Route1">
    Route 1 - {{ message }}

    <br/>

    <alert ng-repeat="alert in alerts"
           type="alert.type"
           close="closeAlert($index)">{{alert.msg}}</alert>
</div>

and finally the route1.js -

angular.module('myapp').controller('Route1', ['$scope', function($scope) {
    $scope.message = 'Hello, world!'

    $scope.alerts = [
        { type: 'danger', msg: 'Oh snap! Change a few things up and try submitting again.' },
        { type: 'success round', msg: 'Well done! You successfully read this important alert message.' }
    ];

}]);
Problem courtesy of: jaime

Solution

The problem is that it's reloading your "myapp" module dependencies. Just config ocLazyLoad not to reload foundation like this:

$ocLazyLoadProvider.config({
    loadedModules: ['mm.foundation']
});

It will be something like that:

var myapp = angular.module('myapp', ['ui.router', 'oc.lazyLoad', 'mm.foundation'])

myapp.config(function($stateProvider, $urlRouterProvider, $ocLazyLoadProvider){

  // For any unmatched url, send to /route2
  $urlRouterProvider.otherwise('/route2')

  $ocLazyLoadProvider.config({
        loadedModules: ['mm.foundation']
    });

  $stateProvider
    .state('route1', {
        url: "/route1",
        controller: 'Route1',
        templateUrl: "route1.html",
        resolve: {
            loadCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
                return $ocLazyLoad.load({
                    name: 'myapp',
                    files: ['route1.js']
                })
            }]
        }
    })
    .state('route2', {
        url: "/route2",
        templateUrl: "route2.html"
    })
});

$(function() {
    Foundation.global.namespace = '';
    $(document).foundation();
})
Solution courtesy of: Olivier

Discussion

Replace this code

<alert ng-repeat="alert in alerts"
           type="alert.type"
           close="closeAlert($index)">{{alert.msg}}</alert>

by

<div ng-repeat="alert in alerts">
  <alert type="alert.type" close="closeAlert($index)">{{alert.msg}}</alert>
</div>
Discussion courtesy of: Alexei

I finally managed to make this work. The problem was that ocLazyLoad was reloading the 'myapp' module. This caused the dependencies to reload. One of the dependencies was mm.foundation which reprocessed all the directives creating a clone of each pair.

To prevent this,I did not tie the second controller to myapp. Instead I created a new app 'route1app'. You can see the updated plunker here: http://goo.gl/lhtD0c

Discussion courtesy of: jaime

This recipe can be found in it's original form on Stack Over Flow.