Angular2 how to set templateUrl base path

2020-02-11 12:12发布

问题:

In Angular2, I have something like templateUrl = 'templates/app.component.html' during development. But in deployment, i need the url to be something like templateUrl = '/static/angular_templates/app.component.html'. It bites to have to change the url at every single place. Is there an easy way to set a base url and do something like

templateUrl = BASE_TEMPLATE_PATH+ '/app.component.html'

so i only need to update BASE_TEMPLATE_PATH when switching from development to production? Thanks!

回答1:

With TypeScript you can use static variables, like :

export class AppTemplateConstants {

    public static get BASE_TEMPLATE_PATH(): string { return 'YOUR_PATH_HERE'; }

}

To import this :

import { AppTemplateConstants } from '../shared/constants/AppTemplateConstants';

To use this :

templateUrl: AppTemplateConstants.BASE_TEMPLATE_PATH + 'app/path/component.html'


回答2:

You can achieve the desired effect without changing the templateUrl all over your code base by using UrlResolver, available since 2.0.0-alpha.36.

import {UrlResolver} from '@angular/compiler';
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

let MyApp: any;

@NgModule({
  imports: [BrowserModule],
  providers: [{provide: UrlResolver, useValue: new UrlResolver("http://localhost/app")}],
  bootstrap: [MyApp]
})
class AppModule {
}

export function main() {
  platformBrowserDynamic().bootstrapModule(AppModule);
}

This will bootstrap your application with a custom instance of UrlResolver that has a base url that you specify. You can even have finer control over resolving the paths by extending the UrlResolver class:

class MyUrlResolver extends UrlResolver {
  resolve(baseUrl: string, url: string): string {
    // Serve CSS files from a special CDN.
    if (url.substr(-4) === '.css') {
      return super.resolve('http://cdn.myapp.com/css/', url);
    }
    return super.resolve(baseUrl, url);
  }
}

@NgModule({
  imports: [BrowserModule],
  providers: [{provide: UrlResolver, useClass: MyUrlResolver}],
  bootstrap: [MyApp]
})
...

(source)

Note: for this to work, you most likely need to use component-relative paths by providing moduleId: module.id, in your component definition, e.g.:

@Component({
    moduleId: module.id,  // use component-relative paths
    selector: 'dialogs',
    templateUrl: './dialogs.html',
})


回答3:

I use DependencyInjection to pass around an EnviromentSettings object where I store environment variables such as BASE_TEMPLATE_PATH.

Kind of simple and nice mechanism in my opinion.

I hope it helps



回答4:

You should define a constant in your build environment, using webpack, for example, you can use the webpack.DefinePlugin: Passing environment-dependent variables in webpack



回答5:

you can use one common class/service in which you can store all your global variables and inject that class at the time of bootstrapping by doing so that class is now available to all another classes/components throughout the app and also now you can easily change your variable value by just changing at one place instead of making changes in all components here is example of same -

import {Component, Injecable} from 'angular2/core';

@Injecable()
export class GlobalService {
public BASE_TEMPLATE_PATH: string;

    constructor() {
        this.BASE_TEMPLATE_PATH = "Your Path Goes Here";
    }
}

and just register this service class in bootstrap like this -

bootstrap(AppComponent, [
  HTTP_PROVIDERS,GlobalService , XYZ...
]);

Now this GlobalService class is available to all another classes,

also now no need to register this class in the list of providers every time when you use because angular itself initialize this to all components, Now use these global variables/function in any class like this -

import {GlobalService} from './GlobalService';
...// stuff here
templateUrl: GlobalService.BASE_TEMPLATE_PATH + 'app/path/component.html'


标签: angular