问题
I have found some behaviour of an x3d inserted in an Angular (version 4) component which I think is really strange.
I have created an Angular project with the following structure:
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
I added the x3dom
library to package.json
and to sysytemjs.config.js
.
My index.html
looks like this:
<!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>
The X3D file (red_box.x3d
) showing the small red box that I want to render is:
<?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>
The code of the home
component is the following:
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() { } }
The problem arises in the viewer
component. The code of the files which form this component is the following:
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); }) } }
My Angular application goes from component home
to component viewer
, and viceversa, via routing. The routes are defined in the file 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);
I noticed something really strange. Every time that I refresh the website, the first time that I access the component viewer
, the scene is empty. However, the subsequent times that I access this component via routing (without refreshing), the box is rendered inside the scene.
However, if I replace the inline
tag in the file viewer.component.html
by <inline url="red_box.x3d"> </inline>
, this does not happen (the box is rendered even the first time the website is refreshed).
Does anyone have any ideas on how could I fix this strange behaviour? I need to define the URL of the inline
tag in the file viewer.component.ts
.
I am very new to Angular and to web development, and I am getting mad about this. Any help would be appreciated, thanks.
回答1:
As Shane van den Bogaard suggested, the problem is solved by replacing [url]
with [attr.url]
in the file viewer.component.html
. Also, it is necessary to modify the file viewer.component.ts
. Its content now should be the following:
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'));
}
}
来源:https://stackoverflow.com/questions/44312860/angular-and-x3d-integration-strange-behaviour