大家下午好!
我的任务是在一个组件中加载两个外部模块。我通过渲染指令加载外部脚本。问题是只加载了最后一个,加载时第一个被“覆盖”。当我创建一个新元素时,我发现这都是关于渲染的。如何解决?
home.component.html
<div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="nav-home-tab">
<searchTourSimple [script]="'src/app/scripts/homeSearch.js'"></searchTourSimple>
</div>
<div class="shop-window">
<div id="shopwindow-container">
<shopWindow [script]="'src/app/scripts/shopwindow.js'"></shopWindow>
</div>
</div>
dir1.directive.ts
@Directive({
selector: 'searchTourSimple'
})
export class SearchModuleSimpleDirective implements OnInit {
@Input('script') param: any
script: any
constructor(private renderer:Renderer2) { }
ngOnInit() {
this.script = this.renderer.createElement('script')
this.script.type = 'text/javascript'
this.script.src = this.param
this.script.async = true
this.renderer.appendChild(document.head, this.script)
document.write = function(input: string) {
document.getElementById('home').innerHTML += input
}
}
}
dir2.directive.ts
@Directive({
selector: 'shopWindow'
})
export class ShopWindowDirective implements OnInit {
@Input('script') param: any
script: any
constructor(private renderer:Renderer2) { }
ngOnInit() {
this.script = this.renderer.createElement('script')
this.script.type = 'text/javascript'
this.script.src = this.param
this.script.async = true
this.renderer.appendChild(document.head, this.script)
document.write = function(input: string) {
document.getElementById('shopwindow-container').innerHTML += input
}
}
}
你的问题是第二个指令也补丁
document.write,所以第一个指令已经使用了第二个指令修补的方法并将其设置innerHTML为document.getElementById('shopwindow-container').这里不需要指令,如果我从源代码中理解正确,那么您正在尝试使用指令加载外部资源
.js,您通常需要将此业务逻辑隔离到某种服务中,我们称之为ScriptService:我们在做什么?该方法
loadResource返回一个流,并在外部资源 (onload) 完全加载后触发一个事件。patchDocumentWrite- 只是补丁document.write,并将要设置的元素的标识符作为参数innerHTML。在方法loadExternalResources中,我们创建了一个空流(后续管道需要)。在加载脚本之前,homeSearch我们将对其进行修补document.write并以相同的方式继续。在这个实现中,我们一个一个地加载脚本,但这给了我们一个保证,一个指令不会比另一个更快地修补方法。我们也不使用
Renderer2它(这不是必需的)。现在我们需要订阅该方法返回的流loadExternalResources以运行整个管道,我们可以在ngAfterViewInit组件的根目录中执行此操作: