我发现在Angular(版本4)组件中插入了x3d的一些行为,我觉得这很奇怪。
我创建了一个具有以下结构的Angular项目:
x3d_and_angular/
app/
home/
home.component.css
home.component.html
home.component.ts
index.ts
viewer/
viewer.component.css
viewer.component.html
viewer.component.ts
index.ts
app.component.html
app.component.ts
app.module.ts
app.routing.ts
main.ts
app.css
index.html
package.json
red_box.x3d
sysytemjs.config.js
我将x3dom
库添加到package.json
和sysytemjs.config.js
。
我的index.html
看起来像这样:
<!DOCTYPE html>
<html>
<head>
<base href="/" />
<title>X3D and Angular Integration</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- bootstrap css -->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<link rel='stylesheet' type='text/css' href='http://www.x3dom.org/download/x3dom.css'>
<!-- application css -->
<link href="app.css" rel="stylesheet" />
<!-- polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function (err) { console.error(err); });
</script>
<script>
function show_inline_url(){
console.log(document.getElementById("inline_element"));
}
</script>
</head>
<body>
<app>Loading ...</app>
</body>
</html>
显示我要渲染的小红框的X3D文件(red_box.x3d
)是:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.3//EN" "http://www.web3d.org/specifications/x3d-3.3.dtd">
<x3d>
<head>
<meta name="title"/>
</head>
<Scene>
<Shape id="shape_id">
<appearance>
<material diffuseColor='1 0 0'></material>
</appearance>
<box></box>
</Shape>
</Scene>
</x3d>
home
组件的代码如下:
home.component.html
:
<div>
<a [routerLink]="['/viewer']">X3D Viewer</a>
</div>
home.component.ts
:
import { Component, OnInit } from '@angular/core';
@Component({
moduleId: module.id,
templateUrl: 'home.component.html',
styleUrls: ['home.component.css'],
})
export class HomeComponent{
constructor() { }
}
问题出现在viewer
组件中。构成此组件的文件的代码如下:
viewer.component.html
:
<div>
<x3d width='600px' height='400px'>
<scene>
<inline id="inline_element" [url]="x3d_filename"> </inline>
</scene>
<a [routerLink]="['/']"><span>BACK</span></a>
</x3d>
</div>
viewer.component.ts
:
import { Component, OnInit } from '@angular/core';
declare var System: any;
@Component({
moduleId: module.id,
templateUrl: 'viewer.component.html',
styleUrls: ['viewer.component.css'],
})
export class ViewerComponent implements OnInit{
x3d_filename: string = "red_box.x3d";
constructor() {
this.importX3d();
}
ngOnInit(){
if(window["x3dom"] != undefined){
window["x3dom"].reload();
}
}
importX3d():void{
System.import('x3dom').then(() => {
console.log('loaded x3d');
}).catch((e:any) => {
console.warn(e);
})
}
}
我的Angular应用程序从组件home
转到组件viewer
,反之亦然,通过路由。路由在文件app.routing.ts
中定义:
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/index';
import { ViewerComponent } from './viewer/index';
const appRoutes: Routes = [
{ path: '', component: HomeComponent},
{ path: 'viewer', component: ViewerComponent},
// otherwise redirect to home
{ path: '**', redirectTo: '' }
];
export const routing = RouterModule.forRoot(appRoutes);
我注意到一些非常奇怪的东西。每次刷新网站时,第一次访问组件viewer
时,场景都是空的。但是,随后我通过路由访问此组件(没有刷新),该框在场景内呈现。
但是,如果我将文件inline
中的viewer.component.html
标记替换为<inline url="red_box.x3d"> </inline>
,则不会发生这种情况(即使是第一次刷新网站时也会显示该框)。
有没有人对如何解决这种奇怪行为有任何想法?我需要在文件inline
中定义viewer.component.ts
标记的网址。
我对Angular和Web开发都很陌生,我对此感到很生气。任何帮助将不胜感激,谢谢。
答案 0 :(得分:0)
正如 Shane van den Bogaard 建议的那样,通过将[url]
替换为文件[attr.url]
中的viewer.component.html
来解决问题。此外,有必要修改文件viewer.component.ts
。其内容现在应该如下:
import { Component, AfterViewInit, OnDestroy } from '@angular/core';
declare var System: any;
@Component({
moduleId: module.id,
templateUrl: 'viewer.component.html',
styleUrls: ['viewer.component.css'],
})
export class ViewerComponent implements AfterViewInit, OnDestroy{
x3d_filename: string = "red_box.x3d";
constructor() {
this.importX3d();
}
ngAfterViewInit(){
if(window["x3dom"] != undefined){
window["x3dom"].reload();
}
}
importX3d():void{
System.import('x3dom').then(() => {
console.log('loaded x3d');
}).catch((e:any) => {
console.warn(e);
})
}
ngOnDestroy(){
System.delete(System.normalizeSync('x3dom'));
}
}