I am struggling with a pesky scenario. I have a basic app with three ui-views that change depending on app state. If I code the app following the angular and UI-router guidelines everything fits toghether just fine. However, I want to integrate my own layout management script and I get into trouble very fast.
My script, dynamicLayout
, reads a JSON and inserts DOM elements into a specified root node following a three graph. The script is able to adjust the regions dimensions, and collapse them if necessary (think Photoshop UI panels). Also it allows the user to drag-n-drop panels from one region to another. I found this task much easiear to manage in vanila js due to my incomplete skills in Angular.
<div id="toolbar" ui-view="toolbar" ></div>
<div id="main">
<div id="sidebar-1">
<div ui-view="navigator"></div>
</div>
<div ui-view="content"></div>
</div>
Previously, I tried to initialize dynamicLayout.js
rendering first, then to bootstrap angular manually after rendering finished. This worked pretty good, angular compiled the ui-view directives and then run the data binding process with no fault. Because I created additional views for the login and register screens, I had to revert this pattern. Right now I am trying to render the layout after angular has kicked in. I tried using Resolve and templateProvider, but both have failed.
Resolve manages to render the layout, but as soon as it finishes the layout gets overwritten by templateUrl: 'app/views/scheduler.html'
. I learned that angular assumes that no other framework will touch anything inside the root view node. What I would like is to prevent $compile from inserting the template, and using my injected divs to contiune directive compilation and data binding (just for the main ui-view).
Using Template Provider has proven unsuccesufull for my use case because I need actual dom elements to which I bind various objects and data that enable my layout manager to function. As a last resort I could refactor my layout manager to parse the DOM elements from the main angular template in order to obtain the layout graph, but I am not eager to try this approach due to many other conflicts that will arrise.
Here's a code stub that gives a glimpse of my app.
app.js
var app = angular.module('myApp', ['ui.router']);
app.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
// Main root
$urlRouterProvider.otherwise('/');
// States
$stateProvider
.state('subscription', {
abstract: false,
url: '/',
resolve:{
layout: function () {
JS.load('AppLayout.json', function (response) {
dynamicLayout.init(response);
});
}
},
views: {
'@' : { templateUrl: 'app/views/scheduler.html', controller: 'schedulerController'},
'toolbar@subscription': { templateUrl: 'app/toolbar/toolbar.html', controller: 'toolbarController' },
'navigator@subscription': { templateUrl: 'app/navigator/navigator.html' },
'content@subscription': { templateUrl: 'app/appointments/appointments.html' },
}
})
// Some other states
}]);
scheduller.html
<div id="toolbar" ui-view="toolbar" ></div>
<div id="main">
<div id="sidebar-1">
<div ui-view="navigator"></div>
</div>
<div ui-view="content"></div>
</div>
appLayout.json
{
"regions": {
"id": "layout-root",
"orientation": "vertical",
"elastic": "false",
"children": [
{
"id": "toolbar",
"elastic": "false",
"css": {
"rule": "overflow:hidden;"
},
"attributes": {
"ui-view": "toolbar"
},
"size": {
"start": "44"
},
"plugin": {
"id": "toolbar",
"config": "toolbar"
}
},
// other layout regions
]
}
}