Aurelia Slot Name
Jul 05, 2016 The view you want to load into the layout should specify which content goes where by adding a slot attribute to each element to specify which slot it should be projected to: slot='content1'Some text 1 slot='content2'Some text 2 In the above scenario, the resulting HTML would be. If you do not provide a name for a slot (the default slot) the name of it internally is: au-default-slot-key. We first check if the slot exists and then we check the length of its children, the children array exists inside each slot. If a slot has no HTML projected into it, it will have a children length of zero. Named slots Aurelia has the concept of named slots. This enables one to project items from templates into different slots of for instance a custom component. This is what the hasParts takes advantage of. The issue here is the browser itself, not Aurelia. The browser comes along and it sees the slot element and knows that it is not a valid child element of so it strips it out. This is where the as-element attribute comes into the fray.
I was quite recently involved in a discussion in the Aurelia Gitter chatroom in which Rob Eisenberg (master of Aurelia) and an Aurelia user were discussing a feature which would allow “layouts” for any given route.
To set the scene: a common pattern seen in the chatroom was developers wanting to use a vastly different screen layout for their application depending on if the user was logged in or not.
MVC and ASP.NET have had this since the early days in the form of layouts/master pages.
The Aurelia framework was missing this feature, and attempting to do this with child routers was a bit more painful than it should have been.
I volunteered to have a go at implementing this feature, having had a bit of experience with the internals of the framework.
A layout replaces the view that would have been loaded into the router-view component when navigating, it then projects content from the former into the layout using the new Shadow DOM v1 slots implementation.
Think of it as a sheet of paper with holes cut out where you want your content to fit.
Your layout view should have one or more slot tags to represent the placeholders where you want to project content. It might look something like this:
The view you want to load into the layout should specify which content goes where by adding a slot attribute to each element to specify which slot it should be projected to:
In the above scenario, the resulting HTML would be:
Things to note
- You don’t have to name your slot if there is only one of them, but if you don’t specify a slot name with multiple slots, don’t expect to see more than 1 of your bits of content, only 1 unnamed slot is supported
- The order of elements in your original viewmodel doesn’t matter as they will be lifted from that particular DOM fragment and re-positioned in the slot that matches the attribute you specified
In order to use a layout, you add one or more additional properties on your route config. These are essentially identical to the compose element (just with a layout prefix):
- layoutViewModel – you can specify a viewmodel to load instead of just using a view for your layouts. This viewmodel can have logic associated (so you could inject some configuration store object and hide/show parts of the UI etc).
- layoutView – you will probably use this the most. This specifies which view to render as the layout or overrides the view used when specifying a viewmodel.
- layoutModel – this is an additional parameter that will be sent to the layout viewmodel’s activate hook. I haven’t found a good reason to use this yet, but since compose has it, why not?
Any of the above parameters can also be set on the router-view element which will be used as a default e.g.:
You can also specify a layout per-viewport by adding the above parameters to each viewport specified in your route config:
With the following route config:
You would see your-layout-view.html loaded up with your content projected accordingly.
Here’s a live example:
The bad news is, this was an early implementation using content selectors instead of the new Shadow DOM v1 implementation in the latest framework release, but at least it gives you an idea.
Note: the above demo should have a navigation bar, if it doesn’t resize the right hand preview pane to be larger. If you navigate between the two pages, you can see that the same module is loaded for both pages, but the appearance of the page is completely different (content is loaded into different places).
I was quite recently involved in a discussion in the Aurelia Gitter chatroom in which Rob Eisenberg (master of Aurelia) and an Aurelia user were discussing a feature which would allow “layouts” for any given route.
To set the scene: a common pattern seen in the chatroom was developers wanting to use a vastly different screen layout for their application depending on if the user was logged in or not.
MVC and ASP.NET have had this since the early days in the form of layouts/master pages.
The Aurelia framework was missing this feature, and attempting to do this with child routers was a bit more painful than it should have been.
I volunteered to have a go at implementing this feature, having had a bit of experience with the internals of the framework.
A layout replaces the view that would have been loaded into the router-view component when navigating, it then projects content from the former into the layout using the new Shadow DOM v1 slots implementation.
Think of it as a sheet of paper with holes cut out where you want your content to fit.
Your layout view should have one or more slot tags to represent the placeholders where you want to project content. It might look something like this:
The view you want to load into the layout should specify which content goes where by adding a slot attribute to each element to specify which slot it should be projected to:
Aurelia Slot
In the above scenario, the resulting HTML would be:
Things to note
- You don’t have to name your slot if there is only one of them, but if you don’t specify a slot name with multiple slots, don’t expect to see more than 1 of your bits of content, only 1 unnamed slot is supported
- The order of elements in your original viewmodel doesn’t matter as they will be lifted from that particular DOM fragment and re-positioned in the slot that matches the attribute you specified
In order to use a layout, you add one or more additional properties on your route config. These are essentially identical to the compose element (just with a layout prefix):
- layoutViewModel – you can specify a viewmodel to load instead of just using a view for your layouts. This viewmodel can have logic associated (so you could inject some configuration store object and hide/show parts of the UI etc).
- layoutView – you will probably use this the most. This specifies which view to render as the layout or overrides the view used when specifying a viewmodel.
- layoutModel – this is an additional parameter that will be sent to the layout viewmodel’s activate hook. I haven’t found a good reason to use this yet, but since compose has it, why not?
Any of the above parameters can also be set on the router-view element which will be used as a default e.g.:
You can also specify a layout per-viewport by adding the above parameters to each viewport specified in your route config:
With the following route config:
Using The “layouts” Feature In Aurelia – Charlie's (hopefully ...
You would see your-layout-view.html loaded up with your content projected accordingly.
GitHub - MeirionHughes/aurelia-template-lint: Sanity Check Of ...
Here’s a live example:
See Full List On Github.com
The bad news is, this was an early implementation using content selectors instead of the new Shadow DOM v1 implementation in the latest framework release, but at least it gives you an idea.
Cached
Note: the above demo should have a navigation bar, if it doesn’t resize the right hand preview pane to be larger. If you navigate between the two pages, you can see that the same module is loaded for both pages, but the appearance of the page is completely different (content is loaded into different places).