Angular 和 X3D 集成:奇怪的行为
Angular and X3D integration: strange behaviour
我发现在 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
时,场景都是空的。但是,随后我通过路由访问此组件(无需刷新)时,该框会在场景内呈现。
但是,如果我将文件 viewer.component.html
中的 inline
标记替换为 <inline url="red_box.x3d"> </inline>
,则不会发生这种情况(即使是第一次刷新网站时也会呈现该框) .
有没有人知道我该如何解决这个奇怪的行为?我需要在文件 viewer.component.ts
.
中定义 inline
标签的 URL
我对 Angular 和 Web 开发还很陌生,对此我很生气。如有任何帮助,我们将不胜感激。
正如 Shane van den Bogaard 所建议的那样,通过将文件 viewer.component.html
中的 [url]
替换为 [attr.url]
来解决问题。另外,需要修改文件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'));
}
}
我发现在 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
时,场景都是空的。但是,随后我通过路由访问此组件(无需刷新)时,该框会在场景内呈现。
但是,如果我将文件 viewer.component.html
中的 inline
标记替换为 <inline url="red_box.x3d"> </inline>
,则不会发生这种情况(即使是第一次刷新网站时也会呈现该框) .
有没有人知道我该如何解决这个奇怪的行为?我需要在文件 viewer.component.ts
.
inline
标签的 URL
我对 Angular 和 Web 开发还很陌生,对此我很生气。如有任何帮助,我们将不胜感激。
正如 Shane van den Bogaard 所建议的那样,通过将文件 viewer.component.html
中的 [url]
替换为 [attr.url]
来解决问题。另外,需要修改文件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'));
}
}