Consider this example:
The main router is located in
app.js
- someparent/childroute1
- someparent/childroute2
- route3
"someparent" is the "base controller and view". It has some reusable html markup in the view, custom elements and bindings which is to be shared by all its "child views and controllers". The child views and controllers will access these.
Inside "someparent.html" there's (besides the shared markup) also a <router-view>
tag, in which the child routes and pages should be rendered inside, but there's no navigation inside someparent.html.
From the main router/routes in app.js it should be possible to click a link and land - not on the parent/base class "someparent" itself, but directly on the children of the "someparent" "base/parent views and controllers", rendering both, when you click a link in the navigation menu of app.html built from the routes in app.js (and maybe routes in someparent.js injecting the child router in the parent or what?).
So essentially what I need is to achieve almost the same thing as basic routing - but as I mentioned I need to have multiple of these routes / pages as partials of a parent view/controller. I couldn't find any info on this from googling extensively for weeks, so hopefully someone in here will be able to understand what I ask, and have an idea of how to go about this in Aurelia, the right way?
I'm still relatively new to Aurelia (about 3 months) so there might be a more "expert" answer out there, but what you're trying to do is quite basic. Remember that Aurelia is based completely on components, to the point that every component is basically an element on a page. When rendering the "parent" view/controller, your "child" view/controllers are just elements on that parent page. So you only need to render the parent page and ensure that the child pages are linked correctly.
Router (in app.js):
Parent ViewModel (in someparentfolder/someparent.js)
Parent View (in someparentfolder/someparent.html)
Child 1 ViewModel (in someparentfolder/child1.js)
Child 1 View (in someparentfolder/child1.html)
(Use same concepts for Child 2 ViewModel and View)
Navigation Directly to Child Components:
The above scenario has each of the child components "embedded" in the SomeParent page. However, if you want to simply open each Child Component as its own navigation router view (to open directly in your main
<router-view></router-view>
content window), just use a router definition like this:One More Scenario:
Perhaps what you're looking for is a Singular class that contains a common place to store state and common functions that all of your components will access. I implemented this by creating a model called
core.js
. I've added those details above, and you would also create the following file in your project root (/src
) folder.Core Class (in /src/core.js):
Notes on Binding:
I gave you an example of how to set up two-way binding to the child component with a JavaScript object. Aurelia is very flexible and you could do this a lot of different ways but this seems to be fairly standard. If you don't need the child to manipulate the data contained in
child1
, you could delete the parenthetical notes on the@bindable
decorator so it would simply be@bindable linkeddata;
You can add multiple parameters to link more than one piece of data, or group them into an object or array.
Since I'm still a relatively new user, I remember going through all of this. Please let me know if you have any follow-up comments or questions.
And by all means, if there are any true experts watching this, please teach me as well! :-)
Create a class to contain your shared state and take a dependency on that class in your view-models. You can use the
NewInstance.of
resolver to control when shared state is created vs reused.Here's an example: https://gist.run?id=4cbf5e9fa71ad4f4041556e4595d3e36
shared-state.js
shared-parent.js
note: if you use
@inject(SharedState)
instead of@inject(NewInstance.of(SharedState))
, a single instance ofSharedState
will be shared with all components. This may be what you are looking for, I wasn't sure. The purpose of@inject(NewInstance.of(SharedState))
is to make sure the parent and it's children have their ownSharedState
instance.child-a.js
child-b.js
After better understanding the original question, I would propose the following solution, which takes advantage of the "Additional Data" parameter available in Aurelia's router. For more information, see http://aurelia.io/hub.html#/doc/article/aurelia/router/latest/router-configuration/4
app.js
someparent.js
someparent.html
Additional thoughts:
I tested the above and it works. Hopefully by using the route settings data parameters you can "get the message through" to the parent router as to which child you want displayed. Depending on your specific application, you may prefer to implement this as a sub-router, but simply binding/unbinding the individual child views as I've demonstrated above is a simple solution. It also shows you how to access the extra parameters you can supply with each route in Aurelia's router.