让我们有角度的项目。出于性能原因,我们希望应用程序在webworkers中运行,这是可以的,因为Angular团队有可能这样做。
我们的应用程序需要实现DOM操作库(谷歌地图)。因此我们需要使这个模块在主线程上运行,在那里可以进行DOM操作。但是,我们仍然希望在网络工作者中完成所有繁重的工作。
为了解决这个问题,我将对外部库的所有调用都包含在一个文件中。为方便起见,此文件是模块的服务。
map
- component.ts
- service.ts
- module.ts
- template.html
- styles.css
export class MapComponent implements OnInit, OnDestroy {
constructor(private mapService: MapService, element: ElementRef, renderer: Renderer2)
this.mapService.element.then(map => {
renderer.appendChild(element.nativeElement, map)
})
}
}
@Injectable()
export class MapService {
private static worker = new Worker('./worker.js')
public map: google.maps.Map
public element: Promise<Element>
constructor(private http: Http) {
const div = document.createElement('div')
this.map = new google.maps.Map(div, { ... })
this.element = new Promise(resolve => {
// Fetch google map div element as soon as it is availe
google.maps.event.addDomListenerOnce(this.map, 'idle', () => {
resolve(this.map.getDiv())
})
})
MapService.worker.postMessage({ name: 'init', data: ... }])
MapService.worker.addEventListener('message', event => { ... })
}
}
template.html
仅包含<content></content>
。组件从外部库请求服务地图元素,它是div
,然后通过renderer.appendChild(element.nativeElement, div)
添加此div。函数renderer.appendChild
是安全的,但我不确定DOM元素是否能够传递给worker。
要回答的问题:
注意:
encapsulation: ViewEncapsulation.Native
答案 0 :(得分:2)
我认为angular不支持在Web Worker中运行某些模块以及在主线程中运行某些模块的默认支持。 angular中可用的默认支持是使用“ platform-webworker”和“ platform-werbworker-dynamic”模块在Web Worker线程中运行所有业务逻辑(组件和服务)。 要使用此解决方案,您需要确保您的应用程序在组件和服务中没有对窗口,dom,文档等的任何直接引用。
如果很难修改现有应用程序以使其与Web Worker兼容,则仍可以使用Web Worker在Web Worker线程中运行一些CPU密集型代码/逻辑,而其他应用程序则可以继续在主线程中运行
这是一个演示文稿,讨论如何执行此操作: Web Workers In Your Angular Application
演示文稿中示例的源代码 Angular 5和 Angular 6
希望您会发现这很有帮助。