【问题标题】:Angular2 How to get APP_BASE_HREF programmatically?Angular2如何以编程方式获取APP_BASE_HREF?
【发布时间】:2017-01-10 06:39:32
【问题描述】:

如何以编程方式获取 APP_BASE_HREF?

我的 app.module.ts 中有这个(其中 APP_BASE='/'):

{
    provide: APP_BASE_HREF,
    useValue: '<%= APP_BASE %>'
},

我正在尝试:

import { APP_BASE_HREF } from '@angular/common'; 
...
console.debug(APP_BASE_HREF.toString());

在控制台中我得到:

Token appBaseHref

我需要得到:

http://localhost:5555/

【问题讨论】:

    标签: angular


    【解决方案1】:

    如果使用 PathLocationStrategy,Angular 现在有 LocationStrategy.getBaseHref() (https://angular.io/api/common/LocationStrategy)。

    例如在app.module.ts:

    ...
    import { LocationStrategy, PathLocationStrategy } from '@angular/common';
    ...
    @NgModule({
      providers: [
        ...
        {provide: LocationStrategy, useClass: PathLocationStrategy},
        ...
      ],
      ...
    })
    export class AppModule { }
    

    然后在您的服务/组件/...中:

    constructor(private locationStrategy: LocationStrategy, ...) {
      console.log(this.locationStrategy.getBaseHref());
      ...
    }
    

    【讨论】:

    • 我想补充一点,这只有在您使用 PathLocationStrategy 时才有效。 HashLocation 策略返回基本 href 的空字符串。
    【解决方案2】:

    感谢@Günter Zöchbauer的这些回答:

    ...我拼凑了一个这样的方法:


    index.html

    <!DOCTYPE html>
    <html lang="en-us">
    <head>
        <base href="/" />
        <meta charset="utf-8" />
        <title>Testing APP_BASE_HREF</title>
        <link rel="icon" type="image/png" href="favicon.ico" sizes="16x16" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
    </head>
    <body>
            <app-root></app-root>
    </body>
    </html>
    

    app.module.ts

    import { APP_BASE_HREF, PlatformLocation } from "@angular/common";
    import { AppComponent } from "./app.component";
    
    /**
     * This function is used internal to get a string instance of the `<base href="" />` value from `index.html`.
     * This is an exported function, instead of a private function or inline lambda, to prevent this error:
     *
     * `Error encountered resolving symbol values statically.`
     * `Function calls are not supported.`
     * `Consider replacing the function or lambda with a reference to an exported function.`
     *
     * @param platformLocation an Angular service used to interact with a browser's URL
     * @return a string instance of the `<base href="" />` value from `index.html`
     */
    export function getBaseHref(platformLocation: PlatformLocation): string {
        return platformLocation.getBaseHrefFromDOM();
    }
    
    @NgModule({
        declarations: [
            AppComponent
        ],
        providers: [
            {
                provide: APP_BASE_HREF,
                useFactory: getBaseHref,
                deps: [PlatformLocation]
            }
        ],
        bootstrap: [
            AppComponent
        ]
    })
    export class AppModule { }
    

    app.component.ts

    import { Component, OnInit, Inject } from "@angular/core";
    import { APP_BASE_HREF } from "@angular/common";
    
    @Component({
        selector: "app-root",
        templateUrl: "./app.component.html",
        styleUrls: ["./app.component.scss"]
    })
    export class AppComponent implements OnInit {
    
        constructor(@Inject(APP_BASE_HREF) private baseHref: string) {
            console.log(`APP_BASE_HREF is ${this.baseHref}`);
        }
    
        ngOnInit(): void {
        }
    }
    

    app.component.spec.ts

    import { TestBed, ComponentFixture, async } from "@angular/core/testing";
    import { APP_BASE_HREF } from "@angular/common";
    
    describe("AppComponent", () => {
    
        let component: AppComponent,
            fixture: ComponentFixture<AppComponent>;
    
        // configuring dependencies
        beforeEach(async(() => {
            TestBed.configureTestingModule({
                declarations: [
                    AppComponent
                ],
                providers: [
                    {
                        provide: APP_BASE_HREF,
                        useValue: "/"
                    }
                ]
            }).compileComponents();
        }));
    
        // getting component
        beforeEach(() => {
            fixture = TestBed.createComponent(AppComponent);
            component = fixture.componentInstance;
            fixture.detectChanges();
        });
    
        // tests
        it("should create the app", async(() => {
            const app: any = fixture.debugElement.componentInstance;
            expect(app).toBeTruthy();
        }));
    });
    

    然后你可以做这样的事情:

    1. npm start

    APP_BASE_HREF 将等于 index.html 中设置的默认值

    1. npm run build --base-href /foobar/

    APP_BASE_HREF 将等于传递给 base-href 标志的值

    【讨论】:

    • 太棒了!
    • 谢谢!!这解决了我的问题。这是一个必须注入 BaseRef 并将其绑定到所有 src 或 href 引用的 PITA,但至少它确实有效。不明白为什么这个问题还没有解决。
    • 请注意,如果您只想获取基本 href 值,那么现在有更简单的方法。看到这个SO answer
    【解决方案3】:

    只需将其注入到类似的服务或组件中

    import { APP_BASE_HREF } from '@angular/common'; 
    
    ...
    
    constructor(@Inject(APP_BASE_HREF) private baseHref:string) {
      console.log(this.baseHref);
    }
    

    【讨论】:

    • 有效,但只返回 '/'
    • 那么问题就出在哪里设置了。 useValue: '&lt;%= APP_BASE %&gt;' 可能不会达到您的预期。您能否发布完整的提供商列表(provide: APP_BASE_HREF 之前和之后的列表)?
    • 它对我不起作用。我有这个错误信息:No provider for Token appBaseHref
    • 仅供参考:收到此错误:"No provider for InjectionToken appBaseHref"
    • 您需要自己提供providers: [{provide: APP_BASE_HREF, useValue: '/my/app'}]。默认为/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-30
    • 1970-01-01
    • 2010-09-08
    • 2019-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多