在组件模板中,我正在使用ElementRef选择一个svg元素。它工作正常,但是当我构建应用程序并打开它时,elementRef为null。
@Component({
selector: 'app-svg',
template: `<div id="root">
<object [data]='trustedUrl' type="image/svg+xml" height="450" width="650" #dataSvg></object>
</div>`,
styleUrls: ['./svg.component.css']
})
constructor(private sanitizer: DomSanitizer, private elRef: ElementRef) {
}
elementRef定位
@ViewChild('dataSvg') dataSvg: ElementRef;
将其传递给elementRef变量
ngOnInit() {
this.elementRef = this.elRef.nativeElement.querySelector('#dataSvg');
}
加载内容后,我选择了svg:
ngAfterContentInit() {
const elementRef = this.elementRef;
// when content is loaded...
elementRef.addEventListener('load', function (event) {
// ...retrieve svg element
elementRef.querySelector('svg')为空
当我运行' npm run build '并转到dist / index.html时, contentDocument>为空:
答案 0 :(得分:2)
根据 official Doc ,您无法访问@ViewChild
元素,除非您在 AfterView 钩子中进行了此操作( AfterViewInit
或AfterViewChecked
)代替OnInit
。
@ViewChild
,@ViewChildren
,@ContentChild
和@ContentChildren
之间的差异。答案 1 :(得分:2)
您使用@ViewChild('dataSvg') dataSvg: ElementRef;
,但在模板中尚未为dataSvg
提供任何锚点。
有两种方法可以做到这一点:
1)按照Angular Docs中的说明使用@Directive
2)使用模板引用#
:
<object ... #dataSvg></object>
如果已经使用Directive,则未提及,但是在模板代码中,您只有id=dataSvg
答案 2 :(得分:1)
DOM尚未在ngOnInit
中完全构建。您需要等待子级(此处为模板)的创建。
将您的代码而不是ngOnInit
放入ngAfterViewInit
。
有关组件生命周期中的钩子的更多信息,请参见in the Angular documentation。
答案 3 :(得分:0)
我找到了附加SVG元素的兼容性解决方案:
在我的svg组件中,我通过绑定innerHTML设置了svg的源,当我的输入更改时,我正在为svg加载服务,该服务以安全的方式返回svg数据:
在组件中绑定SVG的数据源:
@Component({
selector: 'app-svg',
template: `<div id="root">
<div [innerHTML]="svgSafe" type="image/svg+xml" height="450" width="650" #dataSvg></div>
</div>`,
styleUrls: ['./svg.component.css'] ,
animations: [
]
})
使用输入加载svg的源:
ngOninit() {
var url = this.data.url;
var id = 1;
if(url === 'assets/object_move.svg') {
id = 1;
}
if(url === 'assets/object_wait.svg') {
id = 2;
}
..
var dataSVG;
this
.loaderService
.getSVGData(id)
.subscribe((dataSvg) => {
this.svgSafe = this.sanitizer.bypassSecurityTrustHtml(dataSvg.data);
});
}
答案 4 :(得分:0)
在以下位置,显式给出以下内容:ElementRef,
@ViewChild('dataSvg')dataSvg:ElementRef;
应该是
@ViewChild('dataSvg',{阅读:ElementRef})dataSvg:ElementRef;
答案 5 :(得分:0)
与ElementRef相关的安全风险:
允许直接访问DOM可以使您的应用程序更容易受到XSS攻击。
https://angular.io/api/core/ElementRef#description
考虑使用Renderer2: