0

I'm trying to dynamically create a navigation tree for my left-side nav-panel by recursively creating states for each nav-node (the navigation data is reading from the server's DB).

The template:

<script type="text/ng-template" id="navTree">
  <ul class="nav flex-sm-column">
    <li ng-repeat="node in $ctrl.nodeList">
      <div ng-click="$ctrl.newState(node)">
        <span class="{{node.class}}"></span>&nbsp;{{node.title}}
      </div>
      <div ng-if="node.children.length > 0" ui-view>
      </div>
    </li>
  </ul>
</script>

Ignoring the fetching data and initiating navPanel code, bellow is the navTree state definition code:

let st_navTree = {
  name: 'navTree',
  params: {
    nodeList: []
  },
  controller: ['$transition$', 'runtimeStates', '$state', function ($transition$, runtimeStates, $state) {
    ctrl = this;
    ctrl.nodeList = $transition$.params().nodeList;
    ctrl.newState = function (node) {
      let subStateName = $state.current.name + '.' + node.name;
      runtimeStates.newState(subStateName, st_navTree);
      $state.go(subStateName, {nodeList: node.children});
    };
  }],
  controllerAs: '$ctrl',
  templateUrl: 'navTree'
};

The code that dynamically generating new states (learning from here):

app.provider('runtimeStates', ['$stateProvider', function ($stateProvider) {
  this.$get = function () {
    return {
      newState: function (name, state) {
        $stateProvider.state(name, state);
      }
    };
  };
}]);

The immediate problem is (other problems like re-creating states need to be solved lately):

Although I can see the top level nav-list in the nav-panel; but when I go into the sub menu by clicking an nav-node, instead of adding a sub-view under the parent view, the whole nav-panel's content changes to the sub-state's view, and all parent level views are gone.

I saw another thread and in the comments "this does not work if you change the states with $state.go or $state.transitionTo. Works fine with ui-sref." I worry that $state.go cannot go to the child-state with the parent-view remains.

I'm thinking to change it to ui-sref version, but the dynamic routing will be a new problem which I still have no idea.

zipper
  • 377
  • 1
  • 5
  • 18
  • This behavior is strange. according to [the document](https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views): "When the application is in a particular state—when a state is "active"—all of its ancestor states are implicitly active as well. " But the parent view is obviously not active in my case. – zipper Nov 25 '17 at 02:20

1 Answers1

0

This is an atypical use case for sure... typically if the thing in the URL is dynamic I would be treating it as a query/state parameter but if you really want to have the URLs be dynamically generated it appears this is now baked into the newer versions of UI-Router or available in the ui-router extras as explained here:

Angular - UI Router - programmatically add states

https://ui-router.github.io/ng1/docs/latest/modules/injectables.html#_stateregistry

shaunhusain
  • 19,630
  • 4
  • 38
  • 51
  • Thanks for the answer but it is not what I want because I already made the dynamic creating work. After days I figured it out that the problem is that I generated multi `` tags by the `ng-repeat` without given different names. That is the problem. Still struggling to dynamically assign names. Bellow does not work because it is not evaluated: ``. Any idea? – zipper Nov 25 '17 at 18:36
  • Sorry just really struggling to understand these use cases for the router. So you're dynamically creating new states and dynamically creating places on the screen to put content? I'm not sure this is really a good use case for ui-router honestly. You might be better off doing what you're trying to do by writing your own directive(s) to accomplish the goal. Kind of feels like you're shoehorning ui-router into doing something it wasn't designed to do. – shaunhusain Nov 25 '17 at 19:21
  • Angular uses the $compile services to process any markup look for directives in it and run their corresponding script (pre link, create controller, post link, etc.) in ng-repeat it is creating a new scope for each element of the thing you're repeating over and then compiling the markup and applying that scope to fire the link function for each element in the ng-repeated list. https://github.com/angular-ui/ui-router/issues/2381 – shaunhusain Nov 25 '17 at 19:24
  • I created a [new thread] (https://stackoverflow.com/questions/47494087/ui-router-creating-nested-states-dynamically/47494276#47494276) to demo the issue in the dynamic states walking through, so everyone can test the code and see the real problem; and hopefully fix it. There is a short explain why I'm using this way at the beginning of that thread. – zipper Nov 26 '17 at 09:16