angular-component / router Goto Github PK
View Code? Open in Web Editor NEWAngular Component Router - A declarative router for Angular applications
License: MIT License
Angular Component Router - A declarative router for Angular applications
License: MIT License
The examples have some leftover Angular Router code that should be removed so its more clear
Add commitzen to help with commit message checks
I think the all contributors package is commonly used
Currently we use a route component to define a route.
<route path="/">
<my-component *routeComponent></my-component>
</route>
<route path="/" #myComponenRoute>
<my-component *routeComponent [params>="myComponentRoute.routeParams$ | async"></my-component>
</route>
display: none
on the route elementThis effort would look at potential options to use a structural directive to register the route, and have the route component rendered in its place with no wrapper.
Thoughts
<my-component *route path="/home"></my-component>
<ng-template *route path="/lazy" [load]="components.lazy"></ng-template>
Reference: https://twitter.com/LayZeeDK/status/1285969664917614592?s=20
When lazy loading NgModules and Components, support loading them without the .then
and allow them to be exported as default.
import { Component } from '@angular/core';
@Component({
template: `
<router>
<route path="/lazy" [load]="components.lazy"> </route>
</router>
`,
})
export class MyComponent {
components = {
lazy: () => import('./lazy/lazy.component')
};
}
Currently, the route's redirectTo
handles URLs as absolute.
Relative paths should also be allowed.
With parent router set as
<router>
<route path="/home">
<app-home *routeComponent></app-home>
</route>
<route path="/user/**">
<app-user *routeComponent></app-user>
</route>
<route path="/" redirectTo="/home"></route>
<route path="**">
<app-not-found *routeComponent></app-not-found>
</route>
</router>
And user router set as:
<router>
<route path="/:id">
<app-user-profile *routeComponent></app-user-profile>
</route>
<route path="/">
<app-user-list *routeComponent></app-user-list>
</route>
</router>
Actual:
The following route is handled as correct: '/user/first/second/third' and the UserProfile component would extract id
param as third
.
Expected:
The router responds with 404 and renders the NotFound component.
Use lint-staged to format the changes files and re-add the to the commit
Hi Brandon,
Thank you for this initiative !
Regarding to my experience working with Angular, the router and Drupal, I would like to give you some points to get in mind regarding routing.
In real web projects, I think we can't rely on static urls to route components. Using Drupal as backend, for example, the url are managed by the contributors, and Angular can't know all of them.
For SEO or readability reason, a news can have a url like that :
in english :
https://www.mydomain.com/en/07/14/2020/my-great-news
in french :
https://www.mydomain.com/fr/14/07/2020/ma-super-news
I think we shouldn't trust the url only to take the routing decision and, in fine, the application structure. To my point of view, the Angular defined urls should be only technical/internal and not necessarily displayed.
In the projets I'm working on, I create some routes "templates" by contentTypes (empty paths, component, data etc.). When I get the url, if I don't know what is this url, I ask Drupal for it (on direct access only / app boot), regarding to the content type, I check my route templates to find the right route. Once I found it, I update its path (with the Drupal one, to get also a nice url), if the route is not in the Router configs, then I add it, then I navigateToUrl.
Thanks to this approach I can also mix static routes.
I just wanted to give you another point of view ;-)
Good luck !
This is precondition to guards on RouteComponent using structural directive.
At the moment, each route with structural directive will be registered asynchronously, landing in the routes array most likely after wildcard/catch-all route. Additionally, this allows user to define routes without worrying about the correct order.
Rough logic:
this.routes$ = this._routes$.pipe(scan((routes, route) => {
routes = routes.concat(route).sort((a, b) => {
if (b.path < a.path) { return -1; }
if (a.path < b.path) { return 1; }
if (a.options.exact < b.options.exact) { return -1; } // additional checks for missing `exact` param needed
if (a.options.exact > b.options.exact) { return 1; }
return 0;
});
return routes;
}));
Setup CircleCI configuration and jobs for build/test/lint
Components can access their dedicated URL param via RouteParams
provider.
Sometimes, components need to be aware of all the params in the URL. This should ideally be provided via router service.
Router survive provides access to url$
, queryParams$
, and hash$
stream, but not path params.
Route unregister should be called upon route destroy. Unregistering route will remove it from the routes$
and trigger navigation. This is precondition to having route guards using structural directives.
The intended behaviour is different to @angular/router
canActivate
:
Guard | true | false |
---|---|---|
@angular/router | navigate to route | stop navigation |
angular-routing | navigate to route | navigate to fallback route |
We shouldn't fall too far behind the latest release even if we don't gain much from the latest release
Look at documentation solutions that are easy to manage, and easy to update
Initial Docs should include:
Complete route params observable when route is destroyed
Inputs
The current name angular-routing
is too similar to @angular/router
. This would lead to confusion. Additionally, the name is too generic leading to difficulty when using search engines (searching for angular routing
would most likely point to numerous articles and docs on @angular/router
).
Let's try to brainstorm here possible names in the following format.
Suggested name: FooBar
Explanation(if needed): Foo is to angular was Bar is to routing
Based on the code, the sole purpose of RouteComponentTemplate
is to provide TemplateRef
for RouteComponent to use as the container outlet. These are equivalent:
<route path="/blah">
<app-something *routeComponent></app-something>
</route>
<route path="/blah">
<app-something *ngIf></app-something>
</route>
<route path="/blah">
<ng-template>
<app-something></app-something>
</ng-template>
</route>
Seems unnecessary to define custom directive when ng-template
within RouteComponent could solve this.
What was the reasoning behind it? Is RouteComponentTemplate planned to have some logic in the future?
pathToRegexp
provides nice functionality for parsing routes, but also includes a lot of functionality we do not use or need.
Simple built-in function could reduce footprint further. Take a look at following:
const wrap = (regexBody: string): string => {
return `/^${regexBody}/i`
}
const div = '\/';
const end = '$';
const nEnd = '[]|$'; // null or end
const pathEnd = `[\/#\?]`;
const param = `([^\/#\?]+?)`;
const books = wrap(`${div}books(?:${pathEnd}(?=${nEnd}))?(?=${pathEnd}|${nEnd})`); // '/books' + exact false
const login = wrap(`${div}login${pathEnd}?${end}`); // '/login'
const id = wrap(`(?:${div}${param})${pathEnd}?${end}`); // '/:id'
const home = wrap(`${pathEnd}?${end}`); // '/'
const wildcard = wrap(`(?:${pathEnd}(?=${nEnd}))?`); // '/' + exact false
const booksFind = wrap(`${div}books${div}find${pathEnd}?${end}`); // '/books/find'
const booksId = wrap(`${div}books(?:${div}${param})${pathEnd}?${end}`); // '/books/:id'
const booksRoot = wrap(`${div}books${pathEnd}?${end}`); // '/books'
const booksWildcard = wrap(`${div}books(?:${pathEnd}(?=${nEnd}))?(?=${pathEnd}|${nEnd})`); // '/books' + exact false
With these few common patterns we can describe every route matcher Regexp
Would something like this be a bad idea? And is there some built-in function that would be able to check if route matches pattern (I imagine link active has to be doing something like that).
private action$ = createEffect(() => this._router.url$.pipe(
// url is /products/detail/123
filter((url) => ofRoute('/products/detail/:id', url)),
tap(console.log)
);
The URLSearchParams Web API has all the necessary functionality to serialize/deserialize query parameters.
This will allow us to:
query-string
dependencyThe ComponentRouterModule.forRoot()
is not supported in standalone components' imports.
Error: Component imports must be standalone components, directives, pipes, or must be NgModules.
These methods delegate to the location.back() and location.forward() methods underneath
Loaders can be used to fetch data for the component, run checks such as auth, redirect, and more.
import { Component } from '@angular/core';
@Component({
template: `
<router>
<route path="/lazy"
[load]="components.lazy"
[loader]="() => Promise<Response> | Observable<Response>">
</route>
</router>
`,
})
export class MyComponent {
data$: Observable<Data> = getLoaderData();
constructor(private loaderData$: LoaderData) {}
components = {
lazy: () => import('./lazy/lazy.component')
};
}
With given main router
<router>
...
<route path="/user">
<app-user *routeComponent></app-user>
</route>
...
</router>
And nested router in UserComponent
:
<router>
<!-- this works -->
<route path="/">
<app-user-list *routeComponent></app-user-list>
</route>
<!-- this also works -->
<route path="">
<app-user-list *routeComponent></app-user-list>
</route>
<!-- this does not work -->
<route path="/profile">
<app-user-profile *routeComponent></app-user-profile>
</route>
<!-- this also does not work -->
<route path="profile">
<app-user-profile *routeComponent></app-user-profile>
</route>
</router>
Calling "/user" works but calling "/user/profile" ends up in not found state.
Use with a module federation example, see what works, and fix what's broken.
If I have a link such as
<a linkTo="/">Home</a>
And I'm on a /blog
route, the link shows as /blog/
instead of /
.
Currrently you define routes by using
<router>
<route></route>
</router>
This proposal changes the component to routes
<routes>
<route></route>
</routes>
This aligns with react-router
v6+ syntax for declaring groups of routes
In ast-utils.ts
there are signs of a copy-paste from ngrx
project.
This entire file should be checked for leftovers:
Also update the linkActive directive to included non-anchor tags
Since we have a name, now we need a logo. Ideally, there would be a logo for the whole org angular-component
and a visually compatible logo for the router
.
What we are looking for:
Proposals can be done in vector (SVG), raster (JPG, PNG), or hand-drawn sketch (in which case we will convert it to vector eventually).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.