Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional ui-view

I have a ui-view defined in my root template <div ui-view=""></div>. Is that possible to automatically hide that view if it's content is empty?

I was searching for similar thread for some time but all the people suggests is checking current route or passing vars to rootScope which i don't like. I'm looking for the simplest solution possible - checking if desired view has any content defined and if not - hide it's div (or any other html tag)

like image 924
mbajur Avatar asked Apr 17 '14 20:04

mbajur


2 Answers

I realize this is an old question but there is another way to do this with CSS.

You can use the :empty selector to check for content and hide the ui-view div that way.

like image 141
Lance Avatar answered Nov 12 '22 12:11

Lance


I would like to show or share - my way how to solve that. I would say it is a similar story, if I read the question carefully enough. Otherwise, take it as a hint...

Scenario: we need a place, where we can show something, if needed. And hide that if ... not needed. Let's call it toolbar and let's assume it is defined as a View on the root state, and is intended to be managed by any Child state/controller....

$stateProvider
 .state('myModule', {
    url: "/mm",           // sub root 'mm' like MyModule
    views: {
      'body@': {          // this way we inject into index.html
          templateUrl: ..  // the MyModule root template
          controller: 'RootCtrl',   // the root controller
       },
       'toolbarView@myModule' : { // the view is part of MyModule template
          templateUrl: ..
          controller: ..
       },
       ... // standard defintions of the root state
...

The essence here is that the View should be rendered by default. The visibility will be managed by that View:

  • it should not check: is there any content inside of me...
  • but it should check: Is my Model setting IsVisible set to true?

In fact it would be very simple. In our root controller RootCtrl we can/must declare a Model for our toolbar View:

// inside of the 'RootCtrl'
$scope.ToolbarModel = {
    IsVisible : false,
    ViewUrl : null,
};
$scope.ToolbarModel.close = function(){
    this.ViewUrl : null;
    this.IsVisible = false;
}

And this could be our Toolbar View:

// toolbar class can position this view from the global perspective
<div class="toolbar" 
     ng-show="ToolbarModel.IsVisible" >
     // the view is managing its visiblity by Model values 

   <button class="btn btn-default btn-xs"
           ng-click="ToolbarModel.close()" 
           // anyone can anywhere hide us

   </button>

   // holder class representing some inner scrolling area...
   <div class="holder"
     ng-include="ToolbarModel.ViewUrl" >
     // this way we inject the passed 'ViewUrl'

   </div>
</div>

That's it. The ng included view can contain Directives with Controllers requiring $state, $stateParams... and do a lot.

The good I see here:

  • The view is defined on the root View, so we can position it from a Global perspective
  • No hacking. Pure angular way
    • View is rendered always (in fact once, while beeing part of the Root state) and hides immediately in case IsVisible === false.
    • Any Child in any depth can use it, including the call to the ToolbarModel.close()
    • One click will close() ... not disturbing if not needed
  • we are not creating any extensions here to existing angular an ui-router features, just using what is available

Finally to answer a question:

Is that possible to automatically hide that view if it's content is empty?

Yes, we can anywhere manage the $scope.ToolbarModel.IsVisible.

(NOTE: if needed here is why that model is available in every child What are the nuances of scope prototypal / prototypical inheritance in AngularJS?)

like image 33
Radim Köhler Avatar answered Nov 12 '22 13:11

Radim Köhler