Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using angular component breaks material layout

Having the following in index.html and a simple ui router state that loads a compoment as template

<body ng-app="myApp" layout="column">
    <div class="container" layout="row" flex ui-view>
    </div>
</body>

Defined component using the following template stored in a file

<md-sidenav md-is-locked-open="true" class="red">sidenav</md-sidenav>
<md-content class="green" flex>content</md-content>

Generated code will be

 <body ng-app="myApp" layout="column">
       <div class="container" layout="row" flex ui-view>
          <customizing>
             <md-sidenav md-is-locked-open="true" class="red">sidenav</md-sidenav>
             <md-content class="green" flex>content</md-content>
          </customizing>
       </div>
    </body>

The tag breaks the angular material layouting. If I don't use a component, but just a view like this, the layout will be ok

<body ng-app="myApp" layout="column">
       <div class="container" layout="row" flex ui-view>
          <md-sidenav md-is-locked-open="true" class="red">sidenav</md-sidenav>
          <md-content class="green" flex>content</md-content>
       </div>
    </body>

Any ideas? Also I found this post, but I can't figure out how to use the component as an attribute. Is it possible?

See plnkr sample

like image 449
gmodrogan Avatar asked Jun 09 '16 20:06

gmodrogan


2 Answers

This works okay in Plunker

index.html

<div class="container" flex ui-view>
    <customizing layout="row" layout-fill></customizing>
</div>

If you are wondering about layout-fill, this is from the online docs:

layout-fill forces the layout element to fill its parent container

Edit:

For the Plunker in your comment below try this Plunker

customizing.html

<div layout="row" layout-fill>
    <md-sidenav md-is-locked-open="true" class="red">sidenav</md-sidenav>
    <md-content class="green" flex>content</md-content>
</div>

index.html

<div class="container" flex ui-view>
    <customizing></customizing>
</div>
like image 156
camden_kid Avatar answered Nov 18 '22 11:11

camden_kid


I racked my brain on this for a while, hopefully this post helps someone who stumbles upon this search in the future.

You might think that ui-router or angular 1 components would expose a class definition but as of today you'd be wrong and it doesn't seem like they intend to add it either. See https://github.com/angular/angular.js/issues/14800.

However, you can expose $element service to do what you need fairly easily. As per comments above you need to add a class like layout-fill to your component's host element. You may also want to consider adding layout-column, layout-row or flex to keep the existing inner material layout structure, as described in the angular-material docs. See example below:

// Using ES6(ES2015) to demonstrate
export function SiteComponent() {
  return {    
    controller: SiteController,
    templateUrl: 'app/site/site.html'
  };
}

class SiteController {

  constructor(   
    // expose the host element (ie: component element) using angular.IRootElementService
    $element
  ) {

    // add class to element (per angular-material) 
    $element.addClass('layout-fill layout-column');

  }
}

// This will result in a component markup that looks like this:
// <site-component class="layout-fill layout-column">...<site-component>
like image 38
Chase Oliphant Avatar answered Nov 18 '22 11:11

Chase Oliphant