AngularJS usually assumes it's an SPA (Single Page Application) and is also used to being alone on a page. By default, such apps would be initialized using something an ng-app like this:
- <div ng-app="MyAppName"> ... </div>
In a more complex environment this will fail, because there are more than 1 apps on a page. The most common explanation out there says you should leave away the ng-app attribute and manually start the bootstrap on load - approx. like this:
angular.element(document).ready(function() {
angular.bootstrap(document, ['myApp']);
});
This seems nice, but doesn't fix everything we need. The most important parts missing are:
- When you have multiple apps on a page, the element which must be bootstrapped must have a unique ID just to make sure you can find it in the DOM. For example, if you had 2 gallery apps on the same page, chances are the main DIV-tags are the same - so it's hard to bind it correctly.
- Inside this AngularJS-App you will sometimes need to know what ID the module had - mainly for WebAPI and REST calls (to authenticate with the server).
To solve this, 2sxc offers various automations. Here are the most important options:
Automatically Bootstrap Everything
2sxc will automatically bootstrap all your AngularJS-Apps on a page if they adhere to some simple standards. The core requirements are:
- the attribute sxc-app to mark all tags which should be auto-bootstrapped
- an attribute containing the module-id - typically the id-attribute
So what would this look like? Here's an example:
- <div sxc-app="FeedbackApp" id="app-[Module:ModuleId]" ng-controller="Form as fdbk"> ... </div>
As you can see, in sxc-app you'll find the name of the AngularJS module, just like you would expect with an ng-app tag. The ID is a page-wide unique ID thanks to the module-number added by the server [Module:ModuleId]. And the last attribute is simply the view-model binding to the controller (discussed elsewhere).
Other places to store the ModuleId
In case the id-tag must adhere to another standard (maybe because you're using a special script expecting a specific id) then you can also supply the id in another attribute like iid (short for instance id). This would then look as follows:
- <div sxc-app="FeedbackApp" id="blueimp-gallery" iid="[Module:ModuleId]" ng-controller="Form as fdbk"> ... </div>
Manually Bootstrapping the App
In case you want more control over the initialization, you can always call the sxc-bootstrap yourself. This can be done by adding a script-tag to the end of your template, calling the sxc-bootstrap method. It also allows you to specify more dependencies and similar things. Here's an example of such an init script:
- $2sxc.ng.bootstrap('#app-[Module:ModuleId]', 'FeedbackApp');
Note that the first parameter is either a DOM-element or a jQuery-style pattern to find the element. So here too you should be certain that multiple modules on the same page still work - so we recommend using the [Module:ModuleId] token in your script. Since the token is only rendered in the html-template, this one line of code will have to be in the HTML template.