Angular-2: 根据配置更改网站图标

26

我正在渲染一个动态页面,在我的应用程序中显示菜单和其他项目。 我还想根据管理员配置更改网站图标。

比如说,如果当我的页面加载时配置的网站图标是xyz.png,那么它将显示xyz.png作为网站图标。

如下图所示,新的网站图标应该替换"测试应用程序"旁边的现有图标。现在,如下所示,它显示默认的网站图标。

默认的网站图标


index.html

<!DOCTYPE html>
<html>
<head>
    <base href="/MyFirstAngular2/" >
    <title>Angular 2</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="shortcut icon" id="appIcon" href="/favicon.ico" type="image/x-icon" />
    <link href="css/bootstrap.min.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet" />
    <link href="css/Site.css" rel="stylesheet" />

    <script src="scripts/jquery-2.2.1.min.js"></script>
    <script src="scripts/bootstrap.min.js"></script>
    <script src="scripts/main/shim.min.js"></script>
    <script src="scripts/main/zone.js"></script>
    <script src="scripts/main/reflect-metadata.js"></script>
    <script src="scripts/main/system.src.js"></script>
    <script src="scripts/system.config.js"></script>
    <script>

        document.SYSTEMJS_CONFIG.map.app = 'scripts/configs';

        document.SYSTEMJS_CONFIG.packages.app = { main: 'application.ts', defaultExtension: 'ts' };

        System.config(document.SYSTEMJS_CONFIG);

        System.import('app').catch(function (err) {
            console.error(err);
        });        
    </script>

</head>
<body>
        <application></application>
</body>
</html>

每次组件加载时,我都会得到一个新的favicon,所以您只需从任何组件调用更改favicon图标即可。


你使用什么构建方案?如果没有你所拥有的HTML代码,你的问题就太泛泛了。 - shershen
@Shershen:我已经更新了HTML,请参考。 - Sandip - Frontend Developer
我在这里写了一整篇文章,介绍如何使用Angular的构建系统来正确地实现它:https://medium.com/@benracicot/favicons-for-each-environment-327f5b832bae - Ben Racicot
6个回答

55

在index.html中设置链接标签

<link id="appFavicon" rel="icon" type="image/x-icon" href="favicon.ico">

在你的代码中导入某个地方

import { Component, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';

constructor(@Inject(DOCUMENT) private _document: HTMLDocument) {}

并像这样使用它

this._document.getElementById('appFavicon').setAttribute('href', '/your/icon/path.ico');

Angular 5.0 <

->

Angular 5.0及以上版本

import { DOCUMENT } from '@angular/platform-browser';

import { DOCUMENT } from '@angular/platform-browser'; - Phil
这是正确的答案。像@fdsfdsfdsfds建议的那样使用正确的导入。 - Brad Richardson
谢谢@Verri!在找了一段时间后终于找到了这个解决方案,它可以在Chrome、Firefox和IE11上完美运行(需要为客户提供支持)。 我们的设置是通过CircleCI运行的,因此circle-ci.xml配置将base-href设置为每个环境的不同内容。 - user1653042
3
这个解决方案在 Angular 8.0 或更新版本中有效。`import { DOCUMENT } from '@angular/common';` - Harrison O

3

这份代码很好用,不需要注入也无需担心,非常简洁明了。但是在你的angular项目中,它会成为纯javascript代码。

document.getElementById('appFavicon').setAttribute('href', '/your/icon/path.ico');

1

我们在后端运行nodejs,我们需要显示特定于URL的favicon。

在app.js中,我们实现了一个resolveConfig()函数,它将帮助我们获取特定于URL的配置。

上述函数的返回值在获取favicon调用中被使用,如下所示。

app.js

app.get('/favicon.ico',(req,res)=> {
   let key = resolveConfig(req.hostname);
   switch (key) {
     case 'a':
       res.sendFile(__dirname + '/dist/assets/a.ico');
       break;
     case 'b':
       res.sendFile(__dirname + '/dist/assets/b.ico');
       break;
   }
});

index.html

<link rel="icon" type="image/x-icon" href="favicon.ico"/>

*如果你的后端使用nodejs,这可能会很有用。


-2

然后,您可以使用JavaScript通过将以下函数添加到<script>块来根据配置设置网站图标:

 <script>

        document.SYSTEMJS_CONFIG.map.app = 'scripts/configs';

        document.SYSTEMJS_CONFIG.packages.app = { main: 'application.ts', defaultExtension: 'ts' };

        System.config(document.SYSTEMJS_CONFIG);

        System.import('app').catch(function (err) {
            console.error(err);
        });        

//here favicon is set
(function() {
    var link = document.createElement('link');
    link.type = 'image/x-icon';
    link.rel = 'shortcut icon';
    link.href = '../path/to/xyz.png'; //path to selected favicon file
    document.getElementsByTagName('head')[0].appendChild(link);
}());

    </script>

它应该从组件中设置,因为我在组件中获取新图标,并且它将随页面动态变化。 - Sandip - Frontend Developer

-2

app.module.ts

import {NgModule} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {BrowserModule} from '@angular/platform-browser';
import {AppComponent} from './path/to/app.component';
import {AppService} from './path/to/app.service';
// ....

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        // ...
    ],
    bootstrap: [AppComponent],
    providers: [AppService]
})
export class AppModule {}

platformBrowserDynamic().bootstrapModule(AppModule);

app.service.ts

import { Injectable, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Rx';


@Injectable()
export class AppService {

    constructor(@Inject(DOCUMENT) private _document: HTMLDocument, private http:Http) 
    getAppDetails(appId: string) {

            return this.http.post(url, appId)
                .map((response: Response) => {
                    let details = response.json();
                    return details;
                })
                .do(data => console.log(data))
                .catch(this.handleError);
    }

     private handleError(error: Response) {
        console.error(error);
        return Observable.throw(error.json().error || 'Server error');
    }

    setAppFavicon(id: string, basepath: string, icon: string){
       this._document.getElementById('appFavicon').setAttribute('href', basepath+"/"+ icon);
    }
}

app.component.ts:

import {Component} from "@angular/core";
import {AppService} from "../path/to/app.service";


@Component({
    selector: 'application',
    templateUrl: './path/to/app.component.html'
})
export class ApplicationComponent {

    details: any;

    constructor(private appService: AppService) {

        this.details = appService.getAppDetails(id);
        appService.setAppFavicon(id,basepath,this.details.icon);

    }


}

17
我无法相信这个回答会收到这么多的赞,因为它建议使用jQuery修改文档对象模型。 - Phil
6
当然。Angular有许多与DOM相关的引擎可以做到这一点。绝不要使用jQuery。 - Brad Richardson
6
永远不要在Angular中使用jQuery,不应该在Angular组件生命周期外操纵DOM。 - Samuel Ayvazyan
如何在不订阅服务方法getAppDetails()的情况下获取数据,并直接传递给setAppFavIcon()。如果端点需要一些时间才能返回结果,该怎么办? - Aman Agarwal

-6

<application></application>之外,您只能使用Title类:

import {Title} from '@angular/platform-browser';

export class YourClass(){

  constructor(private title: Title){}

  yourNameMethod(){
    this.title.setTitle('your title');
  }
}

1
我已经设置了标题,正如您在图片中看到的那样,现在我想设置网站图标,您能帮我吗? - Sandip - Frontend Developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接