Angular无法读取未定义新对象的属性

时间:2018-09-21 13:54:42

标签: angular three.js

这里的代码中似乎有些我不理解的东西。它一直在抛出错误,尽管在我看来一切都正确。可能有人可以发现它...

我知道这个类很长,但是我认为插入整个代码会更好。当我尝试使用this.scene.add(object)将3D模型添加到场景中时,它在createScene()方法内崩溃了,尽管场景已经使用this.scene = new THREE.Scene()在此方法的顶部进行了初始化尝试使用空对象在类顶部初始化它,但这无济于事。

说实话,Angular还很陌生,不知道在哪里查找错误。错误显示为无法读取未定义的属性“场景”

最奇怪的是,如果注释掉该行,则在create light方法中使用相同的行来添加光,这似乎很好。 obj 3D模型也可以很好地加载,并且不会放入错误括号中,所以我猜不是。

如果有人发现错误,将非常感谢。谢谢。

        import { AfterContentInit, Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core';
        import * as THREE from 'three-full';

        @Component({
          selector: 'app-home',
          templateUrl: './home.component.html',
          styleUrls: ['./home.component.css']
        })
        export class HomeComponent implements  AfterContentInit {  

        private renderer: THREE.WebGLRenderer;
        private camera: THREE.PerspectiveCamera;
        private cameraTarget: THREE.Vector3;
        public scene: THREE.Scene = {make: null};
        public fieldOfView: number = 60;
        public nearClippingPane: number = 1;
        public farClippingPane: number = 1100;
        public controls: THREE.OrbitControls;

        @ViewChild('canvas')
        private canvasRef: ElementRef;

        constructor() {
                this.render = this.render.bind(this);
                this.onModelLoadingCompleted = this.onModelLoadingCompleted.bind(this);
        }


        ngAfterContentInit() {
          this.createScene();
          this.createLight();
          this.createCamera();
          this.startRendering();
          this.addControls();
        }


        private get canvas(): HTMLCanvasElement {
            return this.canvasRef.nativeElement;
        }

        private createScene() {
            this.scene = new THREE.Scene();
            var objLoader = new THREE.OBJLoader();
            var myMan: any = {};

            objLoader.load(
                // resource URL
                '/assets/man.obj',
                // called when resource is loaded
                function ( object ) {
                myMan = object;
                this.scene.add(object);
                },
                // called when loading is in progresses
                function ( xhr ) {

                console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

                },
                // called when loading has errors
                function ( error ) {

                console.log( 'An error happened' );


                }


              );


        }

        public render() {
            this.renderer.render(this.scene, this.camera);
        }

        private onModelLoadingCompleted(collada) {
            var modelScene = collada.scene;
            this.scene.add(modelScene);
            this.render();
        }

        private createLight() {
            var light = new THREE.PointLight(0xffffff, 1, 1000);
            light.position.set(0, 0, 100);
            this.scene.add(light);

            var light = new THREE.PointLight(0xffffff, 1, 1000);
            light.position.set(0, 0, -100);
            this.scene.add(light);
        }

        private createCamera() {
          let aspectRatio = this.getAspectRatio();
          this.camera = new THREE.PerspectiveCamera(
              this.fieldOfView,
              aspectRatio,
              this.nearClippingPane,
              this.farClippingPane
          );

          // Set position and look at
          this.camera.position.x = 10;
          this.camera.position.y = 10;
          this.camera.position.z = 100;
        }

        private getAspectRatio(): number {
          let height = this.canvas.clientHeight;
          if (height === 0) {
              return 0;
          }
          return this.canvas.clientWidth / this.canvas.clientHeight;
        }

        private startRendering() {
          this.renderer = new THREE.WebGLRenderer({
              canvas: this.canvas,
              antialias: true
          });
          this.renderer.setPixelRatio(devicePixelRatio);
          this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);

          this.renderer.shadowMap.enabled = true;
          this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
          this.renderer.setClearColor(0xffffff, 1);
          this.renderer.autoClear = true;

          let component: HomeComponent = this;

          (function render() {
              //requestAnimationFrame(render);
              component.render();
          }());
        }

        public addControls() {
          this.controls = new THREE.OrbitControls(this.camera);
          this.controls.rotateSpeed = 1.0;
          this.controls.zoomSpeed = 1.2;
          this.controls.addEventListener('change', this.render);

        }

        public onMouseDown(event: MouseEvent) {
          console.log("onMouseDown");
                event.preventDefault();

                // Example of mesh selection/pick:
                var raycaster = new THREE.Raycaster();
                var mouse = new THREE.Vector2();
                mouse.x = (event.clientX / this.renderer.domElement.clientWidth) * 2 - 1;
                mouse.y = - (event.clientY / this.renderer.domElement.clientHeight) * 2 + 1;
                raycaster.setFromCamera(mouse, this.camera);

                var obj: THREE.Object3D[] = [];
                this.findAllObjects(obj, this.scene);
                var intersects = raycaster.intersectObjects(obj);
                console.log("Scene has " + obj.length + " objects");
                console.log(intersects.length + " intersected objects found")
                intersects.forEach((i) => {
                    console.log(i.object); // do what you want to do with object
                });
        }

        private findAllObjects(pred: THREE.Object3D[], parent: THREE.Object3D) {
          // NOTE: Better to keep separate array of selected objects
          if (parent.children.length > 0) {
              parent.children.forEach((i) => {
                  pred.push(i);
                  this.findAllObjects(pred, i);                
              });
          }
        }

        public onMouseUp(event: MouseEvent) {
          console.log('Mouse Up');
        }

        @HostListener('window:resize', ['$event'])
            public onResize(event: Event) {
                this.canvas.style.width = "100%";
                this.canvas.style.height = "100%";
                console.log("onResize: " + this.canvas.clientWidth + ", " + this.canvas.clientHeight);

                this.camera.aspect = this.getAspectRatio();
                this.camera.updateProjectionMatrix();
                this.renderer.setSize(this.canvas.clientWidth, this.canvas.clientHeight);
                this.render();
            }

            @HostListener('document:keypress', ['$event'])
            public onKeyPress(event: KeyboardEvent) {
                console.log("onKeyPress: " + event.key);
            }



        }

1 个答案:

答案 0 :(得分:0)

在Java中启动该函数之前,必须有一个指向它的指针。 How to access the correct `this` inside a callback?

private createScene() {
this.scene = new THREE.Scene();
var objLoader = new THREE.OBJLoader();
var self = this;   //ADDED THIS BEFORE FUNCTION START

objLoader.load(
    // resource URL
    '/assets/man.obj',
    // called when resource is loaded
    function ( object ) {

        self.onBodyLoadingCompleted(object);   //CAN REFERENCE THE CORRECT OBJECT NOW

    },
    // called when loading is in progresses
    function ( xhr ) {

    console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

    },
    // called when loading has errors
    function ( error ) {

    console.log( 'An error happened' );


    }


  );

}