集成Angular和X3D(渲染一个简单的长方体)

集成Angular和X3D(渲染一个简单的长方体),angular,typescript,x3d,Angular,Typescript,X3d,我是一个完全的网络开发新手,我完全迷路了 我已经下载了Angular教程中使用的Angular Quickstart,现在我想插入一个简单的x3d元素。为此,我修改了app.module.ts、app.component.ts和index.html文件 修改后的文件app.module.ts为: 我创建的新app.component.ts是: import { Component } from '@angular/core'; @Component({ selector: 'my-app'

我是一个完全的网络开发新手,我完全迷路了

我已经下载了Angular教程中使用的Angular Quickstart,现在我想插入一个简单的x3d元素。为此,我修改了app.module.ts、app.component.ts和index.html文件

修改后的文件app.module.ts为:

我创建的新app.component.ts是:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `<x3d width='600px' height='400px'> 
                <scene> 
                    <shape>     
                        <appearance> 
                            <material diffuseColor='1 0 0'></material>
                        </appearance>       
                        <box></box> 
                    </shape> 
                </scene> 
             </x3d>`,
})
export class AppComponent  { name = 'Angular'; }

当我运行$npm start时,不会显示任何内容,并且浏览器不会出现任何错误,我也无法找出原因。我用的是角度4。如果您能帮助解决此问题,我们将不胜感激。

问题在于,当脚本加载时,X3D会检查X3D元素,并且由于您正在加载包含X3D元素的角度组件,X3D无法找到您的元素。不幸的是,X3D没有提供这样的方法来检查DOM中是否有新的X3D元素

我看到您使用的是Systemjs,您可以在加载appcomponent期间轻松地使用它加载脚本。您必须修改Systemjs的配置文件,并在组件中添加导入语句以加载X3D库。最佳做法是从节点模块加载库。$npm安装-保存x3dom

Systemjs.config:

(function (global) {
  System.config({
    paths: {
      // paths serve as alias
      'npm:': 'node_modules/'
    },
    // map tells the System loader where to look for things
    map: {
      // our app is within the app folder
      'app': 'app',

      // angular bundles
      ...

      // other libraries
      ...
      // load x3d from node modules
      ,'x3dom': 'npm:x3dom/x3dom.js'
    },
    // packages tells the System loader how to load when no filename and/or no extension
    packages: {
      ...
    }
  });
})(this);
要使用组件加载库,可以向组件类添加构造函数,并使用Systemjs调用x3d的importstatement

应用程序组件

import { Component } from '@angular/core';

// simple declaration to prevent the tscompiler from causing an compiling error
declare var System : any;

@Component({
  selector: 'my-app',
  template: `<x3d width='600px' height='400px'>
                <scene>
                    <shape>
                        <appearance>
                            <material diffuseColor='1 0 0'></material>
                        </appearance>
                        <box></box>
                    </shape>
                </scene>
             </x3d>`,
})
export class AppComponent  {
  name = 'Angular';
  constructor() {
    System.import('x3dom')
      .then(() => {
        console.log('loaded');
      })
      .catch((e: any) => {
        console.warn(e);
      })
  }
}

现在,每次引导应用程序时,Systemjs都会尝试导入x3dom库。不要忘记在index.html中删除x3dom库的导入,该库会检查window.x3dom是否已经存在。

要允许Angular渲染模块中不存在的元素,必须传递一个模式以允许自定义元素。从@angular/core导入自定义元素\u模式,并将其添加到angular模块的模式数组中。并尝试在角度运行之前加载x3d。我曾尝试导入自定义元素\模式,但这样做会导致浏览器出现许多错误,它抱怨未知元素涉及x3d、材质、外观。。。。这就是为什么我没有导入错误模式的原因。对不起,我完全是web开发的新手。如何使浏览器在Angular应用程序运行之前加载x3d?正如您所建议的,我怀疑这就是问题所在。您可以添加多个模式,因此它是一个数组。显然,当导入脚本并使用自调用函数时,x3d会检查脚本中的x3d元素,并且在编译之后加载应用程序组件。它查询所有x3d元素,在我的例子中,我错了,你必须在你的角度组件渲染后加载x3d。我将在答案中发布解决方案以获得更多字符空间。我发现了一个新问题。当我有一个像你上面描述的那样的组件“a”,它是通过角度布线访问的,我第一次访问“a”时,X3D被适当地渲染。但是,当我第二次访问“A”时,直到我按F5刷新网站时,才会呈现X3D。我认为这是因为x3d.js是缓存的或者类似的东西。你对此有什么想法吗?我是否应该打开一个新的问题,更详细地描述问题?感谢并为我的无知感到抱歉。不,问题是您实际上并没有路由,而是为需要路由的元素加载新的innerhtml。因此,对X3D库的引用仍然处于活动状态。您必须通过删除库并重新导入库来重新加载脚本。我认为做window.x3dom=未定义是最简单的;在导入之前,但这不是很好的做法。在我看来,X3D团队没有实现这样一种方法来重新初始化所有X3D元素的库,这是一个糟糕的设计。您是对的,在访问“a”窗口之前。x3dom是未定义的,之后是定义的。但是,如果我执行window.x3dom=undefined;之后,控制台不断地引发错误,因为应用程序无法访问未定义的getStyle和caps的某些属性,所以我认为应该删除更多内容。有什么想法吗?我通过在window.x3dom未定义时执行window.x3dom.reload修复了这个问题。如果我使用X3D标记内联而不是在模板本身中定义框,那么会发生一些非常奇怪的事情。每次我刷新网站时,第一次访问组件“A”,场景都是空的。但是,在随后通过布线访问此组件时,长方体将在场景中渲染。有什么想法吗?我是否应该发布一个关于这个问题的新问题和一个示例代码?
(function (global) {
  System.config({
    paths: {
      // paths serve as alias
      'npm:': 'node_modules/'
    },
    // map tells the System loader where to look for things
    map: {
      // our app is within the app folder
      'app': 'app',

      // angular bundles
      ...

      // other libraries
      ...
      // load x3d from node modules
      ,'x3dom': 'npm:x3dom/x3dom.js'
    },
    // packages tells the System loader how to load when no filename and/or no extension
    packages: {
      ...
    }
  });
})(this);
import { Component } from '@angular/core';

// simple declaration to prevent the tscompiler from causing an compiling error
declare var System : any;

@Component({
  selector: 'my-app',
  template: `<x3d width='600px' height='400px'>
                <scene>
                    <shape>
                        <appearance>
                            <material diffuseColor='1 0 0'></material>
                        </appearance>
                        <box></box>
                    </shape>
                </scene>
             </x3d>`,
})
export class AppComponent  {
  name = 'Angular';
  constructor() {
    System.import('x3dom')
      .then(() => {
        console.log('loaded');
      })
      .catch((e: any) => {
        console.warn(e);
      })
  }
}