Reputation: 35
In Angular 1.5, the .component() was introduced and seems to be considered good practice. I am currently migrating to ui-router 1.0 which allows (and recommends) routing to components. So I refactored a controller/template route to a component router which works great: The component "example" gets injected to the ui-view container in its own DOM node:
However that breaks my layout (using angular material). The workaround i used is simply copying and using css classes angular material uses for layout on the inserted node. However, i consider this a "hacky" solution: What if angular material changes it's layout module for example?
A better solution would be to add layout attributes or even a css class to the "example" element. But how can i do that? Is that even possible?
I think this question is related to the following, where i provided a workaround for the specific problem. But I am interested in a more generic solution: Using angular component breaks material layout
Upvotes: 3
Views: 463
Reputation: 91
I faced the same problem in my Angular 1.5 project where I also use angular-ui-router and Angular Material components. One possible solution is simply using string-based binding where you bind two attributes into your component: layout and flex. You can give the values for these two bound attributes (usually 'row' and '100' respecively) as you specify your ui-routing state in the following way:
var exampleState = {
name: 'examplestate',
url: '/', // change this to your desired path
component: 'example',
resolve: {
layout: function () {
return 'row'; // you can change this value depending on your UI requirements
},
flex: function () {
return '100'; // you can change this value depending on your UI requirements
}
}
};
In the config method of your module, you define your exampleState in the standard way:
$stateProvider.state(exampleState);
Finally, in the component definition, as you define your bindings, you add these two attributes to the list of bound attributes. Example in Typescript:
export class ExampleComponent implements ng.IComponentOptions {
public bindings: any;
public controller: any;
public template: string;
constructor() {
this.bindings = {
layout: '@',
flex: '@'
};
this.controller = ExampleComponentController;
this.template = ExampleViewTemplate;
}
}
You can add this component to your angular module in the usual way:
.component('example', new ExampleComponent());
This will result in the following HTML element in the DOM (created by angular-ui-router automatically):
<example layout="row" flex="100" class="ng-scope ng-isolate-scope layout-row flex-100">
So in this way you don't need to insert any manual CSS styling in your code. You are using the standard Angular Material attributes on your component-element.
Upvotes: 3