8

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

3
  • can you show the code for the customizing component? this seems to be a case where you would want to use transclusion. Also, components definitely can be defined as an attribute, but again, the code for the component is what is important here. Commented Jun 12, 2016 at 7:23
  • use fiddler and show you code Commented Jun 12, 2016 at 7:24
  • added plnkr sample. Please see the description. My main problem is how to use the components. In the official Angular documentation regarding components it is stated an example with hero-list and hero-item. If hero-item template html is <li>test</li> and hero-list component is an <ul> <hero-item ng-repeat="item in items"> </ul> this will also break the <ul> tag as it is expecting <li> as childs and not <hero-item> of the component. Anyhow.. see the attached plnkr sample, perhaps I'm doing wrong architectural design of the app Commented Jun 12, 2016 at 12:45

3 Answers 3

5
+100

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>
Sign up to request clarification or add additional context in comments.

8 Comments

I agree with you that it works like that, but I need the "ui-view" div as other states of the app will load into that ui-view. Actually I see now that ui-view div is the problem
@gmodrogan Understood
do you have some examples where components are used with ui.router, I need to have a look to see how the guys are doing there.
plnkr.co/edit/ikdMuwZtLSXqn3DetwOO?p=preview Please see this plnkr. I added a new button just to avoid confusion for not using correct routes. As you can see I need to navigate between 2 states. For both states I need the same md-toolbar, but the content is changed via ui-view
|
3

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>

Comments

0

I had to use css to fix that. I am still looking for a cleaner solution, like attaching a class using ui-router. But for now, the following css works for me:

ui-view > *, .ui-view-component-fix > * {
 margin: 0;
 width: 100%;
 min-height: 100%;
 height: 100%;
 flex-direction: row;
 box-sizing: border-box;
 display: flex;
}

Take not that this only works if ui-view has only one child. Furthermore, i consider this a workaround only.

See the plunker forked from your example here: http://plnkr.co/edit/PBittn9UCd1DMaQs9iY2?p=preview

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.