0

I have created a class in my program which uses KineticJS for the "view" part of my MVC design. One of the instance variables in the class is a group which holds multiple rectangular objects. My problem arises when I try to select a specific rectangle in that group by its ID.

I use this.backgroundGroup.get('#id')[0] with no problem in my subMeasure prototype function, but when I try to use it in my drawMeasures prototype function, it stops my canvas from drawing anything. The console in Chrome says "cannot read properties "ids" of undefined".

The only difference between these to uses of the get method is that the subMeasure function is called on the "click" event, and the drawMeasures function is called when View is instantiated.

function View(){
    this.status = 0;
    this.stage;
    //layers
    this.backgroundLayer;
    this.lineLayer;
    this.noteLayer;
    this.scanLayer;
    this.editLayer;
    this.UILayer;
    //groups
    this.backgroundGroup;
    //edit buttons
    this.subMeas;
    this.addMeas;
    this.edit;

    this.backgroundArray;
    this.lineArray;
}

View.prototype.initialize = function(){
    //Initialize stage
    this.stage = new Kinetic.Stage({
    container: 'tab',
    width:1200,
    height: 400
    });

    //Initialize layers
    this.backgroundLayer = new Kinetic.Layer();
    this.lineLayer = new Kinetic.Layer();
    this.noteLayer = new Kinetic.Layer();
    this.scanLayer = new Kinetic.Layer();
    this.editLayer = new Kinetic.Layer();
    this.UILayer = new Kinetic.Layer();

    //Initialize edit layer
    this.edit = new Kinetic.Rect({
        x:0,
        y:5,
        width:40,
        height:20,
        fill: 'gray',
        stroke: 'black',
        strokeWidth: 2
    });
    this.subMeas = new Kinetic.Rect({
        x:40,
        y:5,
        width:40,
        height:20,
        fill: 'blue',
        stroke: 'black',
        strokeWidth: 2
    });
    this.addMeas = new Kinetic.Rect({
        x:80,
        y:5,
        width:40,
        height:20,
        fill: 'red',
        stroke: 'black',
        strokeWidth: 2
    });
    this.addEditButtonListeners();
    this.editLayer.add(this.edit);
    this.editLayer.add(this.subMeas);
    this.editLayer.add(this.addMeas);

    //Initialize Background Layer
    this.initBackgrounds();
    this.drawBackgrounds();
    this.backgroundLayer.add(this.backgroundGroup);

    //Initialize Line Layer
    this.initLines();
    //Initialize Note Layer
    this.initNotes();

    //Add everything to the stage and display
    this.stage.add(this.backgroundLayer);
    this.stage.add(this.lineLayer);
    this.stage.add(this.noteLayer);
    this.stage.add(this.scanLayer);
    this.stage.add(this.editLayer);
    this.stage.add(this.UILayer);
}    

View.prototype.initBackgrounds = function() {
    this.backgroundGroup = new Kinetic.Group({
        x:20,
        y:80
    });
    for(var i=0; i<controller.MAX_MEASURES; i++){
        this.backgroundGroup.add(new Kinetic.Rect({
            x: i*80,
            y:0,
            width:80,
            height:220,
            fill: 'gray',
            stroke: 'black',
            strokeWidth: 1,
            id: i + '',
            name: i + ''
        }));    
    }
    this.drawBackgrounds();
    this.backgroundLayer.add(this.backgroundGroup);
}

View.prototype.drawBackgrounds = function() {
    var temp;
    for (var i=0; i<numMeasures; i++){
        temp = this.backgroundGroup.get('#'+i)[0];
        temp.setVisible(true);
    }
    for ( i; i<controller.MAX_MEASURES; i++){
        temp = this.backgroundGroup.get('#'+i)[0];
        temp.setVisible(false);
    }
}



View.prototype.addEditButtonListeners = function() {
    this.edit.on('click', function(){
        controller.toggleEdit();
    });
    this.subMeas.on('click', function(){
        controller.subMeasure();
    });
    this.addMeas.on('click', function(){
        controller.addMeasure();
    });
}



View.prototype.toggleEdit = function() {
    if(isEdit){
        this.subMeas.setVisible(false);
        this.addMeas.setVisible(false);
        this.stage.draw();
        isEdit = 0;
    }else {
        this.subMeas.setVisible(true);
        this.addMeas.setVisible(true);
        this.stage.draw();
        isEdit = 1;
    }
}



View.prototype.subMeasure = function() {
    var temp;
    numMeasures--;
    temp = this.backgroundGroup.get('#'+numMeasures)[0];
    temp.setVisible(false);
    this.stage.draw();
} 

backgroundGroup is instantiated as a KineticJS group in initBackgrounds, where it gets 8 rectangles added to it, each with id 0 through 7.

The problematic get call occurs in drawBackgrounds. The non-problematic get call occurs in subMeasure.

JSFiddle link:

http://jsfiddle.net/7xfLq/7/

EDIT: I coded a workaround - I created a backgroundArray that holds the rectangles as well, and access this array in the draw backgrounds method. I don't like it though, I'd rather just keep the rectangles in the group.

4

1 に答える 1

0

要素がステージに追加される前に、キネティック ルックアップ メソッドを呼び出そうとしました。

Chrome デベロッパー ツールを使用して「{}」ボタンを使用すると、縮小されたコードがきれいに出力されるため、コール スタックを調べて問題のあるコードの出所を見つけることができます。この場合Stage、 を実行しようとしたときに定義されていませんでしたget()

JSLint は、使用するのに適したツールです。JSFiddle で実行した場合のコードに関する他の問題を特定しました。

これは、エラーを生成しないコードへのリンクです。

http://jsfiddle.net/7xfLq/11/

最後に 1 つ - コード化されていないコードを実行しようとしないでください。そのブロックのコードの実行が停止するからです。完了していないメソッド呼び出しをコメントアウトするだけです。

于 2012-12-25T03:07:56.643 に答える