我想在我的网页上实现(ASP.NET Core SPA模板(使用Angular 2+ - 使用yeoman生成)Leaflet地图。
所以我在leafletjs.com上搜索教程
首先测试这个例子(它可以作为独立工作):
function(p1,p2..,pk)
我尝试将它与Angular 2+一起使用并创建一些简单的组件,如<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css"
integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet.js"
integrity="sha512-A7vV8IFfih/D732iSSKi20u/ooOfj/AGehOKq0f4vLT1Zr2Y+RX7C+w8A1gaSasGtRUZpF/NZgzSAu4/Gc41Lg=="
crossorigin=""></script>
<style>
#map { height: 180px; }
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = L.map('map').setView([50.0817444,19.9253805], 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
L.marker([50.0817444,19.9253805]).addTo(map)
.bindPopup('A pretty CSS3 popup.<br> Easily customizable.')
.openPopup();
</script>
</body>
</html>
我已经完成了以下步骤:
LeafletMapComponent.
"dependencies": { ... "leaflet":"^1.0.3" ... } "devDependencies": { ... "@types/geojson":"^1.0.2", "@types/leaflet":"^1.0.60" }
entry: { vendor: [ '@angular/common', '@angular/compiler', '@angular/core', '@angular/http', '@angular/platform-browser', '@angular/platform-browser-dynamic', '@angular/router', '@angular/platform-server', 'angular2-universal', 'angular2-universal-polyfills', 'bootstrap', 'bootstrap/dist/css/bootstrap.css', 'es6-shim', 'es6-promise', 'event-source-polyfill', 'jquery', 'zone.js', 'leaflet', ] }, output: { publicPath: '/dist/', filename: '[name].js', library: '[name]_[hash]' },
import {Component, OnInit} from '@angular/core'; import * as L from 'leaflet'; @Component({ selector: 'leaflet-map', templateUrl: 'leaflet-map.component.html', styleUrls: ['leaflet-map.component.css', '../../../..//node_modules/leaflet/dist/leaflet.css'], }) export class LeafletMapComponent implements OnInit { ngAfterViewInit() { L.map('leafletMap').setView([50.0817444,19.9253805], 13); } ngOnInit() { } }
#leafletMap { height: 400px; width: 600px; } <div id="leafletMap"></div>
但我仍然收到这样的错误:
失败:Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware [0] 发生未处理的异常:调用节点模块失败并显示错误:由于错误,预渲染失败:ReferenceError: 窗口未定义
答案 0 :(得分:3)
您似乎在ASP.NET Core Angular启动器中使用Angular Universal(服务器端渲染)。在服务器端,没有定义窗口对象(LeafletMap可能在内部使用)。
有两种选择:
asp-prerender-module
属性来禁用项目中的服务器端呈现。修改强>
根据选项2,您必须注意在加载第三方库(如jquery或LeafletMap)时没有灵丹妙药。只是import语句本身(如果没有在代码优化中删除)可能会导致服务器端的奇怪副作用。 A&#34;可能&#34;实践(因为没有&#34;最佳&#34;实践)可以实现有条件地加载这些库的服务。
import { Injectable, Inject, PLATFORM_ID, Component, OnInit } from '@angular/core';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
@Injectable()
export class LegacyService {
private _L : any;
private _jquery : any;
public constructor(@Inject(PLATFORM_ID) private _platformId: Object) {
this._init();
}
public getJquery() {
return this._safeGet(() => this._jquery);
}
public getL() {
return this._safeGet(() => this._L);
}
private _init() {
if(isPlatformBrowser(this._platformId)){
this._requireLegacyResources();
}
}
private _requireLegacyResources() {
this._jquery = require('jquery');
this._L = require('leaflet');
}
private _safeGet(getCallcack : () => any) {
if(isPlatformServer(this._platformId)){
throw new Error ('invalid access to legacy component on server');
}
return getCallcack();
}
}
在组件实现上,您还应该实现仅在客户端使用服务的条件分支:
ngAfterViewInit() {
if(isPlatformBrowser(this.platformId)){
this._legacyService.getL().map('leafletMap').setView([50.0817444,19.9253805], 13);
}
}