Inject dynamically generated template in an ui-view, while bypassing templateUrl injection

时间:2015-07-28 16:03:16

标签: angularjs

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 

        ]
    }
}

0 个答案:

没有答案