7

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)

mbajur
  • 4,406
  • 5
  • 49
  • 79
  • Shouldnt all yout views have content? Thats why its a view. What are you trying to do? – Fuzzyma Apr 17 '14 at 20:32
  • 2
    Well, actually no, they shouldnt. I have a sidebar view which is not always filled and i don't want it's container to be visible if it's empty. I can also ask - can i smehow access ui-view variable in my template? It would make me able to use ng-class for instance and deal with it using css – mbajur Apr 17 '14 at 20:37
  • Well. Then I can only refer to the tips you already got. To hide the div with ng-show there has to be a variable set in some scope – Fuzzyma Apr 17 '14 at 20:45
  • Could you hide all the views that end up in that ui-view by default, and then unhide them in their controllers if they have content? – aet Apr 18 '14 at 01:52

2 Answers2

6

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.

Lance
  • 69
  • 1
  • 2
5

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?)

Community
  • 1
  • 1
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Kohler, thank you for your answer. It's helpful but... Is it possible to add some condition in `toolbarView@myModule` to decide if to add it to the root view or not? The issue which I have is that for particular situation I don't want to load it to the DOM. – Kosmonaft Oct 21 '15 at 12:40
  • @Kosmonaft I tried to show you some way here http://stackoverflow.com/a/33264254/1679310 – Radim Köhler Oct 21 '15 at 16:16