Angular 6 routing to lazy loaded nested modules - javascript

I recently started working with Angular 6 and while basic scenarios work pretty well, I'm having a hard time making more complex routing scenarios work.
I have so far divided my application up into two major modules (more to come), Authentication and Core.
In the Core module, I have a Core Component which contains Navigation, Header and Footer Components and then a tag.
From the core navigation the user should be able to access major parts of the application such as:
UsersModule - UserListComponent, AddUserComponent, EditUserComponent etc
ProductsModule - ProductListComponent, AddProductComponent, EditProductComponent etc.
As these different modules will be used by different users I was hoping to use lazy loading to load them into the CoreComponent - router-outlet tag. Ultimately it will look like this:
The problem is I'm not sure how to set up my routing as when I try to load any of the components in either UserModule or ProductModule they just replace the contents of the screen instead of being loaded into the CoreComponent's tag.
Here is the code:
app.module.ts
core.module.ts
user.module.ts
Can anyone please help me?

Related

Create Angular 9 Library (ng-packagr) that allow import of single modules

I created a angular library with angular 9 cli. What I noticed: I can only include modules by loading the whole library:
Of course this makes no sense in a real world application. I want to be able to load each module individually. What am I doing wrong? Why can't he find the image component under #devmonkeys/mark6/image
I linked the repository because I don't know exactly what it is. I think this makes more sense than posting the code of 6 possible files here.
What I mean exactly: #angular/material for example, each component has its own path to avoid loading the whole library into the app during build. https://material.angular.io/components/button/api as an component namend MatButton. to import it we must use: {MatButtonModule} from '#angular/material/button'; i also want this, because it makes no sense to load the whole libary in my code only because i want 1 component.

Is it possible to integrate Angular.js (Angular 1) and AEM (Adobe Experience Manager 6.2)

I cannot include all the things I need an answer to the title, so here is what I concern:
Must a client side framework/lib be required when developing AEM ? If yes what is the best one fits to AEM and easy for development (Angular.js is just the way that I think it is "enough" good and easy for integration).
In case of using angular.js, I have some doubts:
Which is the most outter App (which is initialized with ng-app) and how We load it because AEM component is separated and I can not load most outter in any of them.
IMO, most outter ng-app will be loaded in the template (which is required by all the components, but it is just in theory (I'm not sure about that) and I do not see any example outhere show me how to load JS,CSS files on TEMPLATE creation (not component creation, just for clearly)
Alternative approach, each AEM component will be an separated angular module, and it will bootstraped manually (I'm not sure, too, please help to clarify)
Last but not least, If you have examples (enough complicated, not like hello world) or production project that used this stack (perfect !), please help to let me know, because my biggest concern is "is it possible to do".
Many many thanks in advance !
I am currently using angular JS with AEM successfully.
Which is the most outter App (which is initialized with ng-app) and how We load it because AEM component is separated and I can not load most outter in any of them.
ans: You can create a renderer component for this purpose and make it as an outer app then add the required clientlibs to it. after that you can use the renderers scope as a normal angular application.
IMO, most outter ng-app will be loaded in the template (which is required by all the components, but it is just in theory (I'm not sure about that) and I do not see any example outhere show me how to load JS,CSS files on TEMPLATE creation (not component creation, just for clearly)
ans: Rather than loading it in the template It will pretty easy to add it in the component as a client lib because everything like js / css in AEM we can add it as a client lib
Alternative approach, each AEM component will be an separated angular module, and it will bootstrapped manually (I'm not sure, too, please help to clarify)
ans: Yes you can create a component as an angular application and you can bootstrap it seperately
I have used Angular 1.x with AEM 6.x and created SPA (Single Page Application). Also, created AEM Screens App using Angular 1.x.
There could be many ways to do it, but I have followed the following approach :-
AEM Page template (body tag) with ng-app and added angular dependency for site (clientlib angular 1.x)
Define angular module in your site clientlib(JS) say module.js,
example: var app = angular.module('app', ['ui.router', 'ngAnimate','ui.bootstrap.tpls','ui.bootstrap.modal']);
You can also define state provider for different paths app.config(function ($stateProvider, $urlRouterProvider) {});
Define each component specific module/controller in a specific clientlib(js) file.
example (html): <div ng-controller="LoginCtrl" />
example (client lib(js)) - app.controller('LoginCtrl',
function ($scope) {});

angularjs route to controllers from different modules

At the moment we are in the process of creating a new web application infrastructure.
We initially load a dashboard which is esentially the top bar displaying the logged in user and the set of menus along with it. Clicking on each menu would load a screen (mostly crud screens) in the main section. We areplanning to put each of the crud screens and their components (services, controllers and such) in a seperate module which will encapsulate all the screens from each other, so for example if there is 78 screens there will be 78 seperate modules for each screen. We are also using planing on using Requirejs to load these dependencies dynamically.
The problem however occurs that we need to link the menu with each of the modules for each screen. Typically in a single module based app it would be done like this.
config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/Book/load', {
templateUrl: 'book.html',
controller: 'BookController'
})
.when('/Screen/load', {
templateUrl: 'chapter.html',
controller: 'ChapterController'
});
Where the BookController and ChapterController will be in the SAME module.
However in our case the BookController will be in a BookModule for the book screen and the same applies for the ChapterController. And the routes would be in the initial main module for example AppModule which loads the dashboard initially during startup then.
How would we say for example link the AppModule and the routes with each module for each screen (for example in this case BookController and ChapterController) keeping in mind that we need to load the modules dynamically when NEEDED using requirejs.
(P.S : We are essentially segmenting our application based on feature where feature in our system usually equals screen)
Also any suggestions on any other way we could best structure our app including an answer to the above problem would be very much appreciated.
Regards,
Milinda
Why do you have the route configuration in the initial main module? This creates unnecessary coupling between your modules (ie. your initial module has to know all the possible routes of every module), sort of defeating the purpose of moving your code into modules in the first place.
Each of your modules can have their own route configuration, which will take effect when the modules are loaded. (A consistent naming convention can help avoiding clashes between routes of unrelates modules)
While configuring the routeProvider, you can use lazy loading mechanisms using the resolve attribute of routes: resources referenced here will be resolved before the routeChange event happens, which enables you to wait for any promise resolution or a requireJS loading of a file. This blogpost might help in that regard.
As of this moment, there is no mechanism as far as I am aware for dynamically loading modules at runtime and then incorporating them in an AngularJS app. You can breakdown your app into 78 individual modules loaded via requirejs, but you will still need a single primary module which has all those other 78 as dependencies. It is this primary module which you will then configure all the routes.
There is work going on into a new AngularJS router which borrows from other more flexible routers (i.e. ui-router, etc) which will allow exactly the sort of dynamic loading of modules you are speaking about but as far as I know it won't be available until AngularJS 1.4.

React, async loading for multiple sections/views with different components

I'm having an issue thinking about the best way to architect a React app with multiple pages/views (still a SAP).
Let's say we have a simple app with 4 major sections (pages): dashboard, users, stats, comments. Each section has different components in it (think react components). For example, the comments section would have a hierarchy like so:
CommentsSection
- CommentsQueue
-- Comment
--- Text
--- Buttons
- CommentsApproved
--Comment
--- Text
--- Buttons
In a framework like angular for example, the 4 main sections would be split into partials, and loaded in an ng-view upon request, with their respective components inside. When landing on the homepage, the app would only load the dashboard view and upon the user clicking on a nav item, the selected route (i.e. app/users or app/users/:id) would trigger and the app will load the required "template-view-partial" (without a browser refresh).
Now in terms of React, how would this occur? it seems like ALL views and ALL their components would need to be available in a browserified JS file and the app can then update the DOM.
This seems terribly wrong, as we'd be loading all sections in the first load, even if the user doesn't ever need to get to that section. Granted, we could split it with routes on the server, and only serve the components for the page based on the route, but that would require a browser refresh, where as in Angular for example, it would happen without a browser refresh as the view is loaded asynchronously.
The question is, how can this asynchronous loading happen in a React-based app?
I think there's a few different ways in approaching this, I'll explain the approach that I am currently using for my work and side projects.
Instead of using browserify, we use a module-bundler called webpack (https://github.com/webpack/webpack). What's great about webpack is that it's like Browserify but can split your app into multiple 'bundles'. This is great because if we have multiple components/views, the user would just download the features they need for that particular view without having to download everything initially. It allows react-components and their dependencies to be downloaded on demand.
Pete Hunt wrote an article that goes into depth on the benefits of webpack when using it with React (including how to async load react components), and how it is similar/different to Browserify and modern build tools like Grunt/Gulp: https://github.com/petehunt/webpack-howto
I have described one solution using webpack here : http://blog.netgusto.com/asynchronous-reactjs-component-loading-with-webpack/
In essence :
use require.ensure([], cbk) to define code chunks; in the cbk, load your packages synchronously using require()
in your host component, load your asynchronous component in componentWillMount(), and set in in the host component state.
use it in the host component render, when defined on the state

Single Page Application Organization

Coming from the world of rendering views on the server-side, I can't quite get it to click in my head how to organize the CSS of a single page javascript application. I'm using AngularJS in this particular case.
When doing server-side rendering, it's relatively easy to divide out and organize your CSS files, you can have something like the following:
/css
/layouts
home.css
account.css
...
/components
buttons.css
forms.css
lists.css
...
/modules
account-bar.css
shopping-cart.css
...
and for a given page, say a shopping cart page, you can just include the layout file you need, you can pick the component files unique to the page, and include the shopping-cart module. This results in close to the exact CSS the page needs being delivered.
When it comes to the single page javascript application, I'm a little confused on a few points:
How do you make, say layouts, for each page of the application pages, without having it mess with other pages? Since the page doesn't reload, it seems difficult to make layouts using the generic html elements such as header, nav, section, article, footer, etc. Do you just have to avoid using those elements and instead make divs with separate classes for each page?
I guess this relates to 1, but when you're delivering the CSS (and the JS really) do you just concatenate it all into one giant file? Doesn't making a giant CSS and a giant JS file for a decent size application result in a huge loading time upfront?
I recommend organizing your app by feature, where each feature is an Angular module. See here for an example https://github.com/angular-app/angular-app:
+ src
+ admin
+ users
. admin-users-add.js
. admin-users-add.tpl.html
. admin-users-edit.js
. admin-users.edit.tpl.html
. admin.js
+ home
+ posts
. app.js # bootstrap with requirejs or browserify
+ assets
+ common
. index.html
To answer your 2 questions:
The header and footer would go in index.html (may be imported). For re-usable markup in Angular you'd build a directive that may be common or related to a particular feature. Think of views instead of pages; think of directives instead of containers and selectors.
Yes, for production, everything concatenated in one file, app.min.css and app.min.js
You need some tooling too. With Browserify the workflow is simple, require regular Common modules, then build your browser script.
Separate classes for each page sounds ridiculous :) Look at Twitter Bootstrap - see how they use css classes.
It's faster to create 1 connection and load 1 file than create few connections for loading few small files. New connections opening is a very time consuming thing.

Categories