Use common patterns for different states

I want to be able to use two common components across my application in all states, in the main header and sidebar. I read the docs but I must have missed something. How can I reuse header and sidebar in states

  $stateProvider
    .state('home', {
        url: '/leads:id',
        views: {
          'details': {
              templateUrl: '../views/details.html',
              controllerProvider: function($stateParams) {
                  if($stateParams.id) {
                      return 'CompanyDetails as companydetails';
                  }else {
                      return 'NewCompanyDetailsController as companydetails';
                  }

              }
          },
          'sidebar': {
              templateUrl: '../views/sidebar.html'
            },
          'header': {
              templateUrl: '../views/header.html',
              controller: 'HeaderCtrl as header'
           },
          'vehicledetails': {
              templateUrl: '../views/vehicledetails.html',
              controller: 'VehicleDetailsController as vehicledetails'
          },
          'comments': {
              templateUrl: '../views/comments.html',
              controller: 'CommentsController as comments'
          },
          'saveupdate': {
              templateUrl: '../views/saveupdate.html',
              controller: 'SaveUpdateDetailsController as saveupdate'
          }
        }

    });

      

I want to create another state called "data" for example that reuses the header and sidebar. How can I achieve this without having to rewrite all the components?

I did some reading and now I have an updated state provider that displays a common header and sidebar on all routes, but the data inside the actual container is not displayed at all. Here is my updated code

$stateProvider
        .state('home', {
            abstract: true,
            views: {
              'header': {
                  templateUrl: '../views/header.html',
                  controller: 'HeaderCtrl as header'
              },
              'sidebar': {
                  templateUrl: '../views/sidebar.html'
               }
             },
             resolve: {
                  somedata: function(){return {}}
              }

        })
        .state('home.login', {
            url: '/',
            views: {
               'login@home': {
                          templateUrl: '../views/login.html'
                        }
                }
        })
        .state('home.leads', {
            url: '/leads:id',
            views: {
              'details@home': {
                  templateUrl: '../views/details.html',
                  controllerProvider: function($stateParams) {
                      if($stateParams.id) {
                          return 'CompanyDetails as companydetails';
                      }else {
                          return 'NewCompanyDetailsController as companydetails';
                      }
                  }
              },
              'vehicledetails@home': {
                  templateUrl: '../views/vehicledetails.html',
                  controller: 'VehicleDetailsController as vehicledetails'
              },
              'comments@home': {
                  templateUrl: '../views/comments.html',
                  controller: 'CommentsController as comments'
              },
              'saveupdate@home': {
                  templateUrl: '../views/saveupdate.html',
                  controller: 'SaveUpdateDetailsController as saveupdate'
               }
            }

        });

      

and my index.html

<body ng-app="MyApp">
    <div id="page-wrapper" ng-class="{'open': toggle}" ng-cloak class="open" ng-controller="SlideCtrl">
        <div id="sidebar-wrapper" ui-view="sidebar">
        </div>
        <div id="content-wrapper">
            <div class="page-content">
                    <!-- Header Bar -->
                    <div class="row header" ui-view="header">
                    </div>
                    <!-- Header Bar -->
                    <div ui-view="login"></div>
                    <div ui-view="details"  class="panel panel-default col-xs-11" ></div>
                    <div ui-view="vehicledetails"  class="panel panel-default col-xs-11" ></div>
                    <div ui-view="comments"  class="panel panel-default col-xs-11" ></div>
                    <div ui-view="saveupdate"></div>
            </div>
        </div>
    </div>
    <script src="js/main.js"></script>
</body>

      

+3


source to share


2 answers


I actually managed to get this working now using this link fooobar.com/questions/264047 / ...

I'll explain my answer as I couldn't figure out how it works before I did it myself. You need this to be present for child states to connect to it. https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views#scope-inheritance-by-view-hierarchy-only

Basically you create a main ng-view inside index.html that serves as a container for your rest of the partial files, then you basically contain all the child ui-views inside another layout that will serve as a parent for all states.

So essentially your structure is like this

<body ng-app="MyApp">
<div id="page-wrapper" ng-class="{'open': toggle}" ng-cloak class="open" ng-controller="SlideCtrl">
   <div ng-view>
   </div>
</div>
<script src="js/main.js"></script>

      



and another file with layouts

 <div id="sidebar-wrapper" ui-view="sidebar">
    </div>
    <div id="content-wrapper">
        <div class="page-content">
                <!-- Header Bar -->
                <div class="row header" ui-view="header">
                </div>
                <!-- Header Bar -->
                <div ui-view="login"></div>
                <div ui-view="details"  class="panel panel-default col-xs-11" ></div>
                <div ui-view="vehicledetails"  class="panel panel-default col-xs-11" ></div>
                <div ui-view="comments"  class="panel panel-default col-xs-11" ></div>
                <div ui-view="saveupdate"></div>
        </div>
    </div>

      

Then you basically follow the pattern here

  $stateProvider
    .state('home', {
        abstract: true,
        views: {
            '@': {
                templateUrl: '../views/layouts.html'
                },
            'header@home': {
                templateUrl: '../views/header.html',
                controller: 'HeaderCtrl as header'
            },
            'sidebar@home': {
                templateUrl: '../views/sidebar.html'
             }
         }
    })
    .state('home.login', {
        url: '/',
        views: {
           'login@home': {
                      templateUrl: '../views/login.html'
                    }
            }
    })

      

For all your conditions. This worked for me and I am sure this is the correct way to do it.

0


source


There's a better way:

part of HTML

Index file (index.html):

<html ng-app="app">

<head></head>

<body ui-view></body>

</html>

      



Base file (layout.html)

<header>
    Here the header part
</header>
<aside>
    Here the sidebar part
</aside>
<main ui-view>
    And here is where the app will be ran when you go to a state like "app.home"
</main>

      

States:

var states = {
    'app': {
        templateUrl: 'app/layout.html',
        controller: 'LayoutController as layout'
    },

    'app.home': {
        templateUrl: 'app/home.html',
        controller: 'HomeController as home'
    }
};

angular.forEach(states, function(config, name) {
    $stateProvider.state(name, config);
});

      

0


source







All Articles