GithubHelp home page GithubHelp logo

Comments (10)

mattiLeBlanc avatar mattiLeBlanc commented on April 20, 2024 1

@IvanGarzon Hi mate,

Thanks for your reply.

I think you are mistaken though. It's my believe that by doing a import { ContactModule } from "./common/contact/contact.module" in the Mainstates file and then using loadNgModule it is actually not lazy loading it. In all the example I looked at the lazyload requires a promise and not an import of an module.
I tried it anyway and got an error that app.contact was already defined, which is true since it is defined in the contact module as a forChild definition.

I think the dynamicImport is the way to go since I need something that loads the module dynamically (this is what System did).

Thanks anyway for trying to help me out.

from quickstart-ng2.

christopherthielen avatar christopherthielen commented on April 20, 2024

Sounds like you need to include SystemJS bundle

https://unpkg.com/systemjs/dist/system.js

from quickstart-ng2.

christopherthielen avatar christopherthielen commented on April 20, 2024

Also note that lazy loading has changed A LOT since I coded this quickstart.

You may want to also check out the sample app for Angular which is based on the Angular-CLI

from quickstart-ng2.

christopherthielen avatar christopherthielen commented on April 20, 2024

I updated the quickstart-ng2 to angular 4 and fixed lazy loading.

TL;DR change name: 'app.baz' to name: 'app.baz.**' to mark it as a future state

from quickstart-ng2.

mattiLeBlanc avatar mattiLeBlanc commented on April 20, 2024

@christopherthielen Thanks mate. I will give it a try.

from quickstart-ng2.

mattiLeBlanc avatar mattiLeBlanc commented on April 20, 2024

Is there a way not to have to include SystemJs? I am using MeteorJS and I am not sure if that is based on CommonJS or something else, but it seems weird to have to use SystemJS just to enable the Lazy Loading. Is this really necessary? I see that the example on the ng4 website also uses the SystemJS lib.

from quickstart-ng2.

christopherthielen avatar christopherthielen commented on April 20, 2024

Is there a way not to have to include SystemJs?

Frankly, I don't know. System.import() is as close as we had to a defacto standard for lazy loading code. Note that this doesn't necessarily mean you have to include SystemJS binaries. For example, webpack changes () => System.import() calls into code split points and injects its own lazy loading code instead.

If meteor includes a module loader you could try to use that instead of SystemJS. In some manner you must fetch and load the sources before the NgModule can be lazy loaded into Angular.

from quickstart-ng2.

mattiLeBlanc avatar mattiLeBlanc commented on April 20, 2024

@christopherthielen Hi, Meteor 1.5 added the package dynamic-import which according one of the Meteor guys can help with lazy loading.


import { AppComponent } from "./app.component";
import { Ng2StateDeclaration, loadNgModule } from "@uirouter/angular";


export function loadCrisisModule() {
  return module.dynamicImport( './common/crisis/crisis.module' ).then(( { CrisisModule } ) => {
    console.log( CrisisModule );
    return CrisisModule;
  } );
}
export function loadContactModule() {
  return module.dynamicImport( './common/contact/contact.module' ).then(( { ContactModule } ) => ContactModule );
}
/** The top level state(s) */
export let MAIN_STATES: Ng2StateDeclaration[] = [
  // The top-level app state.
  // This state fills the root <ui-view></ui-view> (defined in index.html) with the AppComponent
  { name: 'app', component: AppComponent },
  { name: 'app.contact', url: '/contact', lazyLoad: loadContactModule },
];

When I use the loadContactModule (or crisisModule loader) I can see the promise resolve since the console.log kicks in and dumps the CrisisModule component source. However, Angular doesn't seem to pick it up and render the state in my ui-view. According to the docs https://ui-router.github.io/ng2/docs/latest/interfaces/state.lazyloadresult.html you are expecting a promise, right.
Any idea how to get the state to render in my ui-view? I think I am almost there.

from quickstart-ng2.

IvanGarzon avatar IvanGarzon commented on April 20, 2024

I was having the same issue with the lazyLoading states that's how I got to this thread. My project is build it using WebpackJS instead of SystemJS.
First of all, thanks for the heads up, you pointed me in the right direction.

Regardless, with the MAIN_STATES file :

import { AppComponent } from "./app.component";
import { Ng2StateDeclaration, loadNgModule } from "@uirouter/angular";

/** Added ContactModule */
import { ContactModule } from "./common/contact/contact.module"

/** The top level state(s) */
export let MAIN_STATES: Ng2StateDeclaration[] = [
  // The top-level app state.
  // This state fills the root <ui-view></ui-view> (defined in index.html) with the AppComponent
  { name: 'app', component: AppComponent },

  // You need to mark app.contact.** as a future state
  // You might not need to use dynamicImport from MeteorJS
  { name: 'app.contact.**', url: '/contact', lazyLoad: loadNgModule( () => ContactModule },
];

In your app.component.html ------> important -----> uiSref="app.contact"

<a uiSref="app.contact" [uiOptions]="{ inherit: false }"  uiSrefActive="active" role="button">
    <span>Contact</span>
</a>

The lazy loaded NgModule must have a state named 'app.contact' which replaces the (placeholder) 'app.contact.**' Future State. Add a 'app.contact' state to the lazy loaded NgModule using UIRouterModule.forChild({ states: CONTACT_STATES }).)

Then, in CONTACT_STATES file

import { Ng2StateDeclaration, Transition } from "@uirouter/angular";
import { ContactComponent } from "./contact.component";
import { ContactDetailComponent } from "./contact-detail.component";

export let CONTACT_STATES: Ng2StateDeclaration[] = [

// A state for the 'app.contact' submodule.
{
    name: "app.contact",
    url: "/contact",
    component: ContactComponent
}

// A child state of app.jokes
{
    name: "app.contact.details",
    url: "/:contactId",
    component: ContactDetailComponent
}
];

And lastly, do not forget import the CONTACT_STATES in your ContactModule

import { NgModule } from "@angular/core";
import { UIRouterModule } from "@uirouter/angular";

import { ContactComponent } from "./contact.component";
import { ContactDetailComponent } from "./contact-detail.component";

import { CONTACTS_STATES } from "./contact.states";

@NgModule({
  imports: [
    UIRouterModule.forChild({ states: CONTACT_STATES })
  ],
  declarations: [
    ContactDetailComponent,
    ContactComponent
  ],
  providers: []
})
export class ContactModule {}

Hopefully this helps to fix your issue @mattiLeBlanc. cheers.

from quickstart-ng2.

IvanGarzon avatar IvanGarzon commented on April 20, 2024
// Angular Router
loadChildren: () => require("./contact/contact.component")["ContactModule"];
or
loadChildren: 'contact/contact.component#ContactModule'

// MeteorJS
export function loadContactModule() {
  return module.dynamicImport( './common/contact/contact.module' ).then(( { ContactModule } ) => ContactModule );
}

// Webpack
/** Lazy Modules */
import { ContactModule } from "./contact/contact.module";
loadNgModule( () => ContactModule

All these three approaches are pretty much equivalent if I am not mistaken.

The concept of lazy loading helps us decrease the startup time of the application. With lazy loading our app does not need to load everything at once, it only needs to load what the user expects to see when the app first loads. Modules that are lazily loaded will only be loaded when the user navigates to their routes, this is why we don not declare them in the main module.

Having said this you only need to remove ContactModule from your imports in your AppModule. Also I forgot to mention that in your AppModule you can still use ----> providers: [{provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader}]

Ps: You can notice that the contact module has been lazily loaded if you check the state in the ui-router visualizer. @mattiLeBlanc

from quickstart-ng2.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.