Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flex-layout is not applying the inline styles on host elements #76

Closed
mcwebdev opened this issue Dec 30, 2016 · 30 comments
Closed

flex-layout is not applying the inline styles on host elements #76

mcwebdev opened this issue Dec 30, 2016 · 30 comments
Assignees
Labels
enhancement P1 Urgent issue that should be resolved before the next re-lease related: angular-core

Comments

@mcwebdev
Copy link

mcwebdev commented Dec 30, 2016

flex-layout is not applying the inline styles on host elements where the host elements are getting their flex-layout attributes via @HostBinding

    @Component({
        selector: 'column-node',  //flex-layout not working on host elements
        host: { '[@visibility]': 'visibility' },
        template: `<ng-content></ng-content>`,
    })    
    
    export class LayoutColumnNodeComponent {
        @HostBinding('attr.fxLayout') fxlayout = 'column';
    }

fxLayout attribute is added in DOM <column-node fxLayout="column"> but flex-layout inline styles are not being applied.

@mcwebdev
Copy link
Author

mcwebdev commented Dec 30, 2016

Added two attributes to the <test-app> selector.
`@HostBinding('attr.fxLayout') fxlayout = 'column';

@HostBinding('attr.fxLayoutAlign') alignment = 'start start'; `

DEMO : plunkr

host

@ThomasBurleson
Copy link
Contributor

K. While this was not an intended usage, it does present some odd ideas.

@ThomasBurleson
Copy link
Contributor

With your hostBindings, your are hoping to set this equivalent?

<test-app fxLayout="column" fxLayoutAlign="start start"></test-app>

but you have only one child within test-app. So what do you expect to happen ?

@mcwebdev
Copy link
Author

mcwebdev commented Dec 30, 2016

My expectation is that <test-app fxLayout="column" fxLayoutAlign="start start"></test-app> get the flex styling applied, I may dynamically add children in later. My issue is that host selectors don't generate any kind of inline flex css. Looking at the inspector in chrome. element.style is empty, however it should not be given the flex properties fxLayout="column" fxLayoutAlign="start start" bound to <test-app>.

element.style should reflect

 {
    box-sizing: border-box;
    max-height: 100%;
    display: flex;
    flex-direction: row;
    -webkit-box-orient: horizontal;
    -webkit-box-direction: normal;
    justify-content: space-between;
    align-items: center;
    align-content: center;
    -webkit-box-align: center;
}```

@mcwebdev
Copy link
Author

hostelements

@ThomasBurleson
Copy link
Contributor

ThomasBurleson commented Dec 30, 2016

I am not certain HostBinding(s) will actually create a compiled, active directive. Most likely it considers the attr.fxLayout to be a static attribute (which is NOT compiled).

This is a known bug/feature request on Angular core.

@mcwebdev
Copy link
Author

mcwebdev commented Dec 31, 2016

This will cause a huge amount of redundant markup in my html files. For every node I will have to code inline all the flex properties rather than setting them once in the reusable component.

my html file will be very busy with all this repeated flex attributes on each selector. Seems I should be able to set this once in the column-node.component.ts

<column-node fxLayout="row" fxLayoutAlign="space-between center" fxFlex.xs="10" fxFlex.sm="25" fxFlex.md="50" fxFlex.lg="100"> 
   ...COLUMN NODE CONTENT...
</column-node>

//could be many nodes cluttering up the file, making it difficult to scan.

<column-node></column-node> would be much cleaner and all the flex attributes set in the column-node.component.ts

`

@ghoullier
Copy link

This feature is under consideration by angular core team angular/angular#11716

@ghoullier
Copy link

@ThomasBurleson the original issue was angular/angular#14114 which is the same that issue here.

@ThomasBurleson
Copy link
Contributor

ThomasBurleson commented Jan 28, 2017

@ghoullier - Thank you for the clarification.

Definitely seems to be a Angular issue: Refs angular/angular#11716

@Twois
Copy link

Twois commented Jun 12, 2017

Is there any update in this issue?

@ThomasBurleson
Copy link
Contributor

@Twois - this issue is not a flex-layout issue, but rather an Angular compiler issue.

@javahaxxor
Copy link

I understood that it sets raw style, but seeing my immediate problem go away I didn't think about the other stuff, thanks for pointing it out.

@mattiLeBlanc
Copy link

mattiLeBlanc commented Oct 7, 2017

@ThomasBurleson

Is it possible to add some kind of marker (^) in front the fxLayout to tell Angular that it needs to $compile this attribute/directive?
It already recognises bindings with [], so it would be nice if you can activate the $compile only when required?

@Component( {
  selector: 'auth',
  host: {
    '^fxLayout': 'column',
  },
  template: `

@ThomasBurleson
Copy link
Contributor

@mattiLeBlanc - No. This is a bug with Angular itself. If your component wants to to have a vertical flow, then simply wrap your component html within a wrapper:

<div fxLayout="column">
   .... your original template content... 
</div>

@mcwebdev
Copy link
Author

mcwebdev commented Oct 9, 2017

@ThomasBurleson Did angular fix this bug, and that's why this issue is now closed?

@dhanarajp
Copy link

@ThomasBurleson i installed flexlayout modules, but its not working in my project can you help what i have to do,

image

Not generating inline style for flexlayout="column"

@mcwebdev
Copy link
Author

@dhanarajp

you need to follow the API...https://github.com/angular/flex-layout/wiki/API-Documentation
fxFlex
fxLayout
fxLayoutAlign etc

@mattiLeBlanc
Copy link

mattiLeBlanc commented Nov 6, 2017

@ThomasBurleson Question (I hope not a silly one), is it possible that 2.0.0-beta.10 is automagically adding style="flex-direction: row; box-sizing: border-box; display: flex;" to the app-root element? I have no reference anywhere for adding this CSS, however it is added. I can't find anything in the docos about this either.

UPDATE
By adding fxFlex to the router-outlet, it added the inline style to my app-root. Is that expected behaviour?
Even if I wrap app.component.html in a <DIV> and add fxFlex to it, it will add the flex-direction: row.

<div fxLayout="column" fxFlex>
  <pro-header *ngIf="!headless"></pro-header>
  <router-outlet></router-outlet>
  <pro-footer *ngIf="!headless"></pro-footer>
</div>

image

Very interesting :)
I am trying to stretch the router-outlet to get a sticky footer at the bottom.
I realise I shouldn't do it on the router-outlet since the real body of the component loaded is appended under the router-outlet. But I found the behaviour interesting.
However, its very hard to stretch the component between the header and footer, since I can't use @HostBindings and wrapping my component template in

<div fxLayout="column">
   .... your original template content... 
</div>

is also not going to stretch the component DOM element. The only way I can do it now is manually assigning a class via @HostBindings to apply the fxFlex behaviour. There must be another way?

@furyscript
Copy link

furyscript commented Nov 27, 2017

I have the same problem.
I'm using resolveComponentFactory to create my component dynamic that is a child of parent and have fxFlexdirective. The problem is that the fxFlex not apply the correcdt width to my host component.

I have attached the result of my page.

I have this main component html

<div fxLayout="row" fxLayoutWrap fxLayoutAlign="start start">
    <template #widgetContainer></template>
</div>

And in the js I fire the createComponent for its children.

This is the content of children HTML:

<div [fxFlex]="this.widget.options.columns">
    <mat-card>
        <mat-card-title>{{this.widget.options.title}}</mat-card-title>
        <mat-card-content>
            Grid {{this.widget.options.columns}}
        </mat-card-content>
    </mat-card>
</div>

And JS:

@Component({
    selector: 'grid',
    templateUrl: './grid.component.html'
})
export class GridComponent implements OnInit {
    public widget: WidgetService;

    public constructor(
        public viewContainerRef: ViewContainerRef
    ) {

        this.widget = new WidgetService({
            title: "Tabella " + this.getIntNum(),
            originalX: 1,
            originalY: 1,
            x: 1,
            y: 1,
            base_columns: 50,
            base_rows: 2,
            columns: this.getIntNum() % 2 == 0 ? 50 : 25,
            rows: 2,
            type: "grid",
            resizable: true
        });
    }

    private getIntNum() {
        let n = Math.floor(+(Math.random()*100));
        return n;
    }

    public ngOnInit(): void {
    }
}

Page result
schermata del 2017-11-27 14-19-39

As you can see the card item not fit the correctly width of my container (container is a full browser page)

@furyscript
Copy link

@ThomasBurleson

@ThomasBurleson
Copy link
Contributor

We have two issues discussed here:

The Host-Directive issue may be fixed... but not in the near-term future. A reasonable interim workaround is the manual use of CSS class for the host-element.

We will reopen this issue to continue exploring other options.

@ThomasBurleson ThomasBurleson added P1 Urgent issue that should be resolved before the next re-lease and removed P2 Issue that is important to resolve as soon as possible labels Dec 28, 2017
@ThomasBurleson ThomasBurleson added this to the v2.0.0-beta.13 milestone Dec 28, 2017
@kylecordes
Copy link

@ThomasBurleson There is already at least one directive in flex-layout (I think fxFlex?) which reaches "up" to its parent to apply CSS styles in certain cases. What about another use of that same notion? There could be a directive which can be used on a top-level element within the component, which reaches upward to configure flex properties on the component element itself.

This could be considered hackish... but has the merit that it could be implemented now, rather than after core Angular signs a high quality solution for the host directive issue.

@gogakoreli
Copy link

gogakoreli commented Feb 28, 2018

Workaround will be to do it by hand, like this.
This is example for fxFlex, I dont want to always write fxFlex on div and use it as spacer, instead I created component and applied fxFlex to the component itself from inside.
This is handy because fxFlex automatically applies styles to the parent container also and there is no other way to do it.

export class SpacerComponent implements OnInit {

    flexDirective: any;

    constructor(
        monitor: MediaMonitor,
        elRef: ElementRef,
        @Optional() @SkipSelf() protected _container: LayoutDirective,
        @Optional() @SkipSelf() protected _wrapContainer: LayoutWrapDirective,
        renderer: Renderer2,
    ) {
        this.flexDirective = new FlexDirective(monitor, elRef, renderer, _container, _wrapContainer);
        this.flexDirective.flex = '1 1 auto';
    }

    ngOnInit() {
        this.flexDirective.ngOnInit();
    }

}

@ThomasBurleson
Copy link
Contributor

@gogakoreli - that is twisted and creative. LOL.
@CaerusKaru - perhaps we should discuss possibilities (and risks) of @kylecordes suggestions above.

@CaerusKaru
Copy link
Member

This has been delayed until post-ivy implementation in Angular core.

@CaerusKaru
Copy link
Member

As an update to this issue, as alluded to by @mhevery in angular/angular#11716, this feature will not be implemented in Core.

The alternative that is being considered is here: angular/angular#8785. Please follow that issue for future updates. I'm closing this issue and locking the conversation since it's very much not a Flex Layout issue.

@angular angular locked as resolved and limited conversation to collaborators Mar 18, 2018
@CaerusKaru CaerusKaru removed this from the Backlog milestone Dec 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement P1 Urgent issue that should be resolved before the next re-lease related: angular-core
Projects
None yet
Development

No branches or pull requests