【问题标题】:Angular environment variable in index.html fileindex.html 文件中的 Angular 环境变量
【发布时间】:2021-10-07 18:24:29
【问题描述】:

我想将 main.ts 中的环境变量放入 index.html <script src="..."> 标记中。 Index.html 看起来像这样:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>RoadFaultReporter</title>
        <base href="./" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" type="image/x-icon" href="favicon.ico" />
        <link rel="manifest" href="manifest.webmanifest" />
        <meta name="theme-color" content="#1976d2" />
        <link rel="preconnect" href="https://fonts.gstatic.com" />
        <link
            href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"
            rel="stylesheet"
        />
    </head>
    <body>
        <app-root></app-root>
        <noscript>Please enable JavaScript to continue using this application.</noscript>
        <script src="https://maps.googleapis.com/maps/api/js?key=MY_KEY"></script>
    </body>
</html>

&lt;script src=""&gt; 中的 MY_KEY 的位置,我想从变量 environment.googleMapsApi 中放置一个键。有没有办法做到这一点?

【问题讨论】:

    标签: angular google-maps


    【解决方案1】:

    不,没有,但你可以用 Angular 的方式来做;通过向 AppModule 添加提供的内容,您可以强制整个应用初始化等到加载谷歌地图。

    下面的代码是我创建的。我在创建 official package 之前创建了它,但我仍然使用我的,因为它没有依赖关系并且缩短了 450 行。

    app.module.ts

    @NgModule({
        //...
        providers: [
            {
                provide: APP_INITIALIZER,
                useValue: () => loadGoogleMaps(environment.googleMapsKey),
                multi: true,
            },
        ],
    })
    export class AppModule {}
    

    加载谷歌地图

    const CALLBACK_NAME = 'initMap';
    
    export enum GoogleMapsLibraries {
        /** provides a graphical interface for users to draw polygons, rectangles, polylines, circles, and markers on the map. Consult the [Drawing library documentation](https://developers.google.com/maps/documentation/javascript/drawinglayer) for more information. */
        drawing = 'drawing',
        /** includes utility functions for calculating scalar geometric values (such as distance and area) on the surface of the earth. Consult the [Geometry library documentation](https://developers.google.com/maps/documentation/javascript/geometry) for more information. */
        geometry = 'geometry',
        /** shows users key places of interest near a location that you specify. Consult the Local [Context library documentation](https://developers.google.com/maps/documentation/javascript/local-context) for more information. */
        localContext = 'localContext',
        /** enables your application to search for places such as establishments, geographic locations, or prominent points of interest, within a defined area. Consult the [Places library documentation](https://developers.google.com/maps/documentation/javascript/places) for more information. */
        places = 'places',
        /** provides heatmaps for visual representation of data. Consult the [Visualization library documentation](https://developers.google.com/maps/documentation/javascript/visualization) for more information. */
        visualization = 'visualization',
    };
    
    export function loadGoogleMaps(googleMapsKey: string, libraries: GoogleMapsLibraries[] = []) {
        if (!window) {
            return Promise.resolve();
        }
    
        return new Promise<void>((resolve, reject) => {
            function onError(err?: any) {
                // eslint-disable-next-line @typescript-eslint/no-empty-function
                (window as any)[CALLBACK_NAME] = () => {}; // Set the on load callback to a no-op
                scriptElement.removeEventListener('error', onError);
                reject(err || new Error('Could not load the Google Maps API'));
            }
    
            // Reject the promise after a timeout
            const timeoutId = setTimeout(() => onError(), 10000);
    
            // Hook up the on load callback
            (window as any)[CALLBACK_NAME] = () => {
                clearTimeout(timeoutId);
                scriptElement.removeEventListener('error', onError);
                resolve();
                delete (window as any)[CALLBACK_NAME];
            };
    
            // Deduplicate libraries
            libraries = [...new Set(libraries)];
    
            // Prepare the `script` tag to be inserted into the page
            const scriptElement = document.createElement('script');
            scriptElement.addEventListener('error', onError);
            scriptElement.async = true;
            scriptElement.defer = true;
            scriptElement.src = `https://maps.googleapis.com/maps/api/js?key=${googleMapsKey}&region=Cz&language=cs&callback=${CALLBACK_NAME}&libraries=${libraries.join(',')}`;
            document.head.appendChild(scriptElement);
        });
    }
    

    【讨论】:

    • APP_INITIALIZER 适用于useValue,而不是useFactory
    • @robert 这在我的情况下有效,在查看文档后认为,正确的方法可能是将它传递给工厂......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-02
    • 2017-07-29
    • 2021-04-15
    • 2020-01-17
    • 2018-03-16
    • 2022-10-17
    • 2017-03-06
    相关资源
    最近更新 更多