I have a child <router-outlet> inside a template that displays various components, based on the menu item clicked. Each child component is responsive, and handles itself well when resizing the page.
The problem is the parent component. In desktop view we need it to be one way, (flexboxes) and in mobile we need it to be another way. What this boils down to is where we put the <router-outlet>.
The obvious solution is to have a couple of <div>s whose classes are set with display: none/block conditionally with a #media query.
And here is where I'm stuck. Angular always chooses the most nested <router-outlet> to use for children. Even though the other one technically no longer exists in the DOM (display: none), the router renders the component inside that outlet.
I looked at named router outlets, but that needs to be set at compile time, in the router config. I need to decide at runtime which outlet to render, based on screen size.
Apparently this is (currently) impossible.
Angular will always choose the most-nested <router-outlet> to house the components, there is no way to determine at runtime.
My workaround was to use an unholy fusion of display: flex, display: grid and #media queries to move the <router-outlet> around the page, using CSS to determine where it will appear.
Related
So i have a website, it is responsive, in small screens the menu is open clicking in a burguer button, when there is enough space the menu is visible in the header and the burguer button dissapear.
My question is what is the best practise to handle this componetes (the burguer is a components that change a context state showMenu).
Should I have 2 diferents Menu components MenuResponsive || MenuInHeader & mount unmount them dependimg on the screen size or only one component with a ton of CSS.
Im using css.module just in case.
thanks
The beauty is that you have options. If the button is going to be reused a lot, I would create a separate component. If not, then I would probably manage responsive design with CSS using media queries or something.
I'm making an Angular-app using Angular Material, and I'm having big issue with the height of my tab content. This is my first attempt at Angular, but I'm familiar with HTML, CSS and JavaScript.
The situation is that I have an app with the MatSidenav component, and inside the Sidenav content I have a MatTab component, which contains a wrapper to load other components dynamically into new tabs. This all works as I want it to, the problem is the content of the tabs, specifically the tabs that get their content after the tab is created (e.g. tabs containing components that load data from the REST service).
I've created a stackblitz based on my actual app, to illustrate the problem.
When going to "Test One" from the menu, it only shows the buttons on the top. The "Get Data" button will simply populate the BehaviorSubject that the data table (AgGrid) uses, (sort of an attempt at simulating a REST-call, which the actual app has). All gets populated and shown as I want, but the container element (one of them, I can't for the life of me figure out which one is the actual cuprit) isn't high enough, so the table doesn't actually show.
The "Test Two" is just an example of a tab with static content, which displays as I expected (same as the Home-tab really).
I've put a button to toggle the height property of the container-div of the table between 500px and blank. Of course, this would be great if I wanted a static height value of 500px (or any px value), but I want it to be as high as the remaining part of the viewport.
I've tried messing with the dynamicHeight property of the mat-tab-group, but if I turn that off it causes a whole deal of other problems since I have tabs with very variable content heights.
I've also tried with various flexbox settings, using both Bootstrap d-flex as well as Angulars own ngFlex, but nothing seems to work.
Now this specific case is for the AgGrid table, but I'm having the same issue with a tab with Google Maps embedded, but I figure if I can solve this one, I'll be able to apply a similar method to fix the maps issue. I'm assuming it is caused by the content changing after the page has been rendered, but that's sort of the point as well, and so that the CSS doesn't seem to keep up confuses the hell out of me.
The only way I've managed to solve this, is by using JavaScript and setting the heights of various elements in ngAfterViewInit and binding an event to window resize, but this seems like a very hack-ish way of doing it, and it also means I have to do it for all components that can be loaded into tabs, not just where I'm currently having problems (because I have to set the height of several of the Tab container elements, which will be the same elements even when tabs are switched).
Any help with this would be greatly appreciated.
I've only used ag-grid sparingly, but I have noticed that they handle height strangely. I think you're missing a 'autoHeight' domLayout property:
<ag-grid-angular
style="width: 100%; height: 100%;"
class="ag-theme-balham mat-elevation-z8"
[rowData]="loadedData"
[columnDefs]="agtablecolumns"
[domLayout]="'autoHeight'"
>
</ag-grid-angular>
Adding that in the stackblitz caused an empty table to appear before any data is retrieved, though. Not sure if that's the goal.
I have a React component that I show/hide based on a button toggle from within its parent component. Instead of just appearing/disappearing on the page, I would like to animate the mounting and unmounting of the component to make it look as if it was sliding down from, and back into the parent. The parent is always visible.
One important note is that there are also components within the first child. One of my attempts involving CSS transitions have resulted in these children being stuck in place when the first child slides up/down. Additionally, Child has no fixed height -- it could be 100px or 1000px.
This is my only animation in the application, so I don't really want to get anything too heavy to drive it. I'm struggling to find what other people are using for this kind of thing.
For that kind of simple animations I generally use CSSTransation. The idea is pretty simple, this component will attach some classes to your element depending on the component state (mounting, unmounting,...), and you have to provide css for the animation.
I finally solved this with a small package called react-animate-height.
<div>
<AnimateHeight
duration={ 500 }
height={ height }
>
<Child />
</AnimateHeight>
</div>
I made a layout container which has as a child as main content, toolbar, and toolbar.
toolbar and footer are dynamic parts and each container or page will have their own toolbar and footer, but layout structure is the same in all pages, so I made multiple layouts and called the related layout component in each container.
but I don't think if it's best practice or not, cause i have too many layouts right now!
so is there any way to define the layout toolbar and footer in child containers and pass them up to the layout?
I know I can use the setState method to put them into the layout state, but I also know that putting the element in the state is not best practice, cause state is for data, not JSX elements or functions.
also, another way that I thought, was putting toolbar and footer using pure javascript using innerHtml of layout toolbar and footer wrapper, but it would be real DOM, not virtual DOM, so it's not best practice either!
so if there's any best practice to having dynamic layout parts based on child component, I would be happy to know them.
thanks
I'm trying to figure out the best way to indicate loading in react between container and presentational elements. Do folks generally avoid any view related items in container elements or do they make an exception for spinner-type elements?
That's a matter of preference, I render content in container elements as needed. A loading spinner is no exception. That being said, if you're intending to put a spinner on the whole page then personally the container is a fine spot for this. If you intend to put a spinner over a form or some content region I'd stick to your presentational component for that.