2012-06-27 4 views
1

У меня возникают проблемы с несколькими экземплярами в одном представлении в разных элементах div. Когда я пытаюсь инициализировать их, появляется только второй из двух элементов независимо от того, в каком порядке я их вставляю.backbone.js - Наличие нескольких экземпляров одного и того же вида

Вот код для моего вида.

var BodyShapeView = Backbone.View.extend({ 
    thingiview: null, 
    scene: null, 
    renderer: null, 
    model: null, 
    mouseX: 0, 
    mouseY: 0, 

events:{ 
    'click button#front' : 'front', 
    'click button#diag' : 'diag', 
    'click button#in' : 'zoomIn', 
    'click button#out' : 'zoomOut', 
    'click button#on' : 'rotateOn', 
    'click button#off' : 'rotateOff', 
    'click button#wireframeOn' : 'wireOn', 
    'click button#wireframeOff' : 'wireOff', 
    'click button#distance' : 'dijkstra' 
}, 

initialize: function(name){ 
    _.bindAll(this, 'render', 'animate'); 

    scene = new THREE.Scene(); 
    camera = new THREE.PerspectiveCamera(15, 400/700, 1, 4000); 
    camera.position.z = 3; 
    scene.add(camera); 
    camera.position.y = -5; 

    var ambient = new THREE.AmbientLight( 0x202020); 
    scene.add(ambient); 

    var directionalLight = new THREE.DirectionalLight(0xffffff, 0.75); 
    directionalLight.position.set(0, 0, 1); 
    scene.add(directionalLight); 


    var pointLight = new THREE.PointLight(0xffffff, 5, 29); 
    pointLight.position.set(0, -25, 10); 
      scene.add(pointLight); 

    var loader = new THREE.OBJLoader(); 
    loader.load("img/originalMeanModel.obj", function (object) { 

     object.children[0].geometry.computeFaceNormals(); 
     var geometry = object.children[0].geometry; 
       console.log(geometry); 
     THREE.GeometryUtils.center(geometry); 
     geometry.dynamic = true; 
     var material = new THREE.MeshLambertMaterial({color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors }); 
     mesh = new THREE.Mesh(geometry, material); 
     model = mesh; 
     // model = object; 
     scene.add(model); 
    }); 

    // RENDERER 
    renderer = new THREE.WebGLRenderer(); 
    renderer.setSize(400, 700); 
    $(this.el).find('.obj').append(renderer.domElement); 

    this.animate(); 

}, 

Вот как я создаю экземпляры

var morphableBody = new BodyShapeView({ el: $("#morphable-body") }); 

    var bodyShapeView = new BodyShapeView({ el: $("#mean-body") }); 

Любая помощь будет очень ценна.

Заранее спасибо.

ответ

1

В вашем методе initialize, вы получаете доступ к глобальным переменным вместо переменных экземпляра: scene = new THREE.Scene(); будет фактически ссылаться window.scene.

Проверить этот пример

var BodyShapeView = Backbone.View.extend({ 
    scene:null, 
    initialize:function(opts) { 
     scene=opts.scene; 
    } 
}); 

var s1=new BodyShapeView({scene:'s1'}); 
var s2=new BodyShapeView({scene:'s2'}); 

console.log(window.scene); //outputs s2 
console.log(s1.scene); //outputs null 

http://jsfiddle.net/K8tjJ/1/

Изменить эти ссылки на this.scene, this.camera и т.д.

var BodyShapeView = Backbone.View.extend({ 
    scene:null, 
    initialize:function(opts) { 
     this.scene=opts.scene; 
    } 
}); 

var s1=new BodyShapeView({scene:'s1'}); 
var s2=new BodyShapeView({scene:'s2'}); 

console.log(window.scene); //outputs undefined 
console.log(s1.scene); //outputs s1 

http://jsfiddle.net/K8tjJ/2/

Кроме того, loader.load использует обратный вызов для обработки своих результатов, вы, вероятно, потеряете ссылку на this в функции. Попробуйте

var _this=this; 
loader.load("img/originalMeanModel.obj", function (object) { 
... 
_this.scene.add(_this.mesh); // or _this.model if you prefer, but beware 

}); 

Обратите внимание, что this.model является специальным переменным в Backbone.View и следует относиться с осторожностью, если вы хотите, чтобы передать модель на ваш взгляд.

+0

Спасибо за ответ @nikoshr, это имеет смысл! Единственная проблема, с которой я сталкиваюсь, заключается в том, что при добавлении модели в сцену в функции загрузчика я получаю эту ошибку. «Uncaught TypeError: не может вызвать метод« add »of undefined» для этой строки this.scene.add (this.model); – TrueWheel

+0

@TrueWheel Радости этого в JS. Я изменил свой ответ, который должен решить вашу проблему. – nikoshr

+0

Спасибо! Работает отлично и отличное объяснение :) – TrueWheel

1

Атрибуту el требуется только строка выбора стиля jQuery. Попробуйте:

var morphableBody = new BodyShapeView({ el: "#morphable-body" }); 
var bodyShapeView = new BodyShapeView({ el: "#mean-body" }); 

UPDATE

Кроме того, ваша проблема может быть, что вы не используете this ключевое слово при определении scene, camera и renderer. Возможно, второе представление переписывает первое представление в результате. Попробуйте:

this.scene = new THREE.Scene(); 
this.camera = new THREE.PerspectiveCamera(15, 400/700, 1, 4000); 

... 

// RENDERER 
this.renderer = new THREE.WebGLRenderer(); 
this.renderer.setSize(400, 700); 
$(this.el).find('.obj').append(this.renderer.domElement); 
+0

Спасибо за ответ, и я боюсь, что у меня по-прежнему возникает такая же проблема, когда появляется только одна. – TrueWheel

+0

@TrueWheel - это первый вид, который создается вообще? то есть оно визуализируется, а затем заменяется вторым представлением? Или, первый вид не получается вообще? – jackwanders

+0

Я думаю, что он заменяется как на консоли THREE.WebGLRenderer и THREE.Geometry отображаются дважды. Спасибо – TrueWheel

Смежные вопросы