Angular和X3D集成:奇怪的行为

时间:2017-06-01 16:33:07

标签: angular typescript x3d

我发现在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.jsonsysytemjs.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开发都很陌生,我对此感到很生气。任何帮助将不胜感激,谢谢。

1 个答案:

答案 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'));
    }

}