1

I'm dealing with a content management system that needs to "inject" a reusable component into a page.

I want to inject the following component (html and javascript).

<script type="text/javascript">
if(typeof angular == 'undefined') {
   document.write(unescape("%3Cscript type='text/javascript' src='/resources/scripts/lib/angular.min.js'%3E%3C/script%3E"));
   document.write(unescape("%3Cscript type='text/javascript' src='/resources/scripts/pricing/app.js'%3E%3C/script%3E"));     }    
}
  </script>           
<div ng-app="pricing" ng-controller="PriceController as pc" ng-init="pc.getPrices('myprod', 'PER')">
 Some text {{ pc.prices.msg["startdat tarief"] | jsDate }} . 
 More text {{ pc.prices.msg["einddat product"] | jsDate }}.

</div>   

The component must be able to be injected multiple times on the page.

The problem is that the controller works fine, but only for the first injection.

This probably has something to do with that I am using the same app multiple times.

I am fairly new to angular.

How can I inject the same component multiple times?

Note that I am not able to init the app on a higher level. Because this would require the content manager to edit all pages, we juist want to inject a HTML component with javascript (i.e. the code snippet).

3
  • Use the right tool for the job.. It's not because Angular is hot at the moment you should use it in all cases. Commented Feb 18, 2015 at 9:38
  • I'm pretty sure you can't declare multiple ng-apps of the same sort. Could you inline the javascript you want to run? Is it big? Commented Feb 18, 2015 at 9:38
  • @DieterGoetelen That comment is not constructive to this question. There are ways to accomplish what OP is trying to do just fine without switching to a whole different framework. Commented Feb 18, 2015 at 9:40

2 Answers 2

3

If you are able to add a unique ID to the module div you can manually bootstrap your angular app as follows:

function bootstrapAngular(id) {
    angular.bootstrap(document.getElementById('module-' + id), ['app']);
}

angular.module('app', []).controller('sample', function ($scope) {
   $scope.foo = 'bar'; 
});

bootstrapAngular(1);
bootstrapAngular(2);
bootstrapAngular(3);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div id="module-1">
    <div ng-controller="sample">
        {{ foo }}
    </div>
</div>
<div id="module-2">
    <div ng-controller="sample">
        {{ foo }}
    </div>
</div>
<div id="module-3">
    <div ng-controller="sample">
        {{ foo }}
    </div>
</div>

Sign up to request clarification or add additional context in comments.

3 Comments

this is a good approach, I have rebuilt it, but now I have the issue that my ng-init runs only once for the first module.
Can't you avoid ng-init? It's a bad practise anyway, why don't you call that method inside your controller?
because the method (controller) needs to be parameterised. I rebuilt the controller using $scope, but it is only initialised once.
2

You cannot have multiple ng-App directives on a single page. From the Angular.js documentation:

Only one AngularJS application can be auto-bootstrapped per HTML document. The first ngApp found in the document will be used to define the root element to auto-bootstrap as an application. To run multiple applications in an HTML document you must manually bootstrap them using angular.bootstrap instead. AngularJS applications cannot be nested within each other.

If placing ng-App higher in the tree isn't an option, you will have to re-write the components so that each component gets a unique angular.module() and when the component is injected, it will need to fire angular.bootstrap().

2 Comments

Multiple ng-app would be possible using iframes, but I am not sure it would help his case though.
I moved away from angularjs in this case and built the controller using jQuery, using jQuery foreach() I can run the ajax call per DIV with a certain ID.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.