Using relative templateUrl in Angular 2

in Front-End Web Technologies

One of the annoying thing using Angular2 templateUrl is that you must use absolute URL. Else, Angular is not able to locate the template.

For example, below definition does not work.

 @Component({
     selector: 'my-app',
     templateUrl: "./app.html",
 })
 export class AppComponent {
     constructor(appRef: ApplicationRef) {
     }
 }

Angular has no knowledge of the current executing module’s URL and therefore is not able to resolve the templateUrl paremeter.

However, CJS modules do offer the current executing module’s URL using a variable named module.id. If you are not familair with the term CJS modules don’t worry. It is just a fancy name for NodeJS modules (require, module & exports variables).

A good module loader (like SystemJS) should support the standard CJS module.id. This means that we can send Angular the current executing module’s URL and use it as the base URL for resolving all other relative URLs.

Here is the fixed code,

 @Component({
     selector: 'my-app',
     moduleId: module.id,
     templateUrl: "./app.html",
 })
 export class AppComponent {
     constructor(appRef: ApplicationRef) {
     }
 }

The module.id value is sent to the @Component decorator. Internally, Angular uses it in order to resolve the relative templateUrl.

Of course, you must use CJS compliant module loader (like SystemJS) in order to enjoy above code. If your are importing scripts into the HTML using the plain old script tag, then above code will not work for you.

BTW, my recommendation is to prefer template over templateUrl.
templateUrl makes Angular life cycle more complex since it must download the template from the server (but this is a story for another post …)

 

Contact us
You might also like
Share: