2012-02-13 259 views
9

我有一個調用一個子視圖骨幹觀點:訪問屬性

lr.MapView = Backbone.View.extend({ 
    el: $('#map'), 
    foo: "bar", 
    initialize: function() { 
     var that = this; 
     _.bindAll(this, "render", "addAllEvents", "addOneEvent"); 
     this.collection = new lr.Events(); 
     this.collection.fetch({ 
     success: function(resp) { 
      that.render(); 
      that.addAllEvents(); 
     } 
     }); 
    }, 

    addAllEvents: function() { 
     this.collection.each(this.addOneEvent); 
    }, 

    addOneEvent: function(e) { 
     var ev = new lr.EventView({ 
     model: e 
     }); 
    }, 

    render: function() { 
    } 
    }); 

這裏是子視圖:

lr.EventView = Backbone.View.extend({ 
    initialize: function() { 
     _.bindAll(this, "render"); 
     console.log(lr.MapView.foo); // will console.log 'undefined' 
    }, 
    render: function() { 
    } 
    }); 

我希望能夠在子視圖中訪問父視圖的屬性,但它不適用於上述代碼。例如,我如何訪問子視圖中的'foo'變量?

回答

10

lr.MapView是一個 「類」,一切Backbone.View.extend建立將在lr.MapView.prototype,而不是在lr.MapView。與控制檯運行此開放,你會看到什麼要去:

var MapView = Backbone.View.extend({ foo: 'bar' }); 
console.log(MapView); 
console.log(MapView.prototype); 
console.log(MapView.prototype.foo); 

演示:http://jsfiddle.net/ambiguous/DnvR5/

如果你只打算有一個MapView的,那麼你可以參考lr.MapView.prototype.foo無處不在:

initialize: function() { 
    _.bindAll(this, "render"); 
    console.log(lr.MapView.prototype.foo); 
} 

注意到處包括內lr.MapView情況下讓你的foo會像一個「類變量」基於非原型OO語言。

做到這一點,正確的方法是使用一個實例變量foo和父視圖實例傳遞到子視圖情況下,他們在創建時:

// In MapView 
addOneEvent: function(e) { 
    var ev = new lr.EventView({ 
    model: e, 
    parent: this 
    }); 
} 

// In EventView 
initialize: function(options) { 
    _.bindAll(this, "render"); 
    this.parent = options.parent; // Or use this.options.parent everywhere. 
    console.log(this.parent.foo); 
} 

或者更好,添加一個訪問方法到MapView

_foo: 'bar', 
foo: function() { return this._foo } 

,並使用在EventView該方法:

initialize: function(options) { 
    // ... 
    console.log(this.parent.foo()); 
} 

即使在JavaScript中,正確的封裝和接口也是一個好主意。

+0

精彩的回答,謝謝。爲什麼訪問器方法比你提到的另一種方法更可取? – AdamVickers 2012-02-13 02:45:52

+2

@AdamVickers:存在一個訪問者向外部世界發出信號:「foo()」是MapView公共接口的一部分,並且缺少一個變異指示外部人不應該改變它。 – 2012-02-13 02:57:01

0

只是一個猜測,但可以嘗試這樣的事情在MapView

addOneEvent: function(e) { 
    var that = this, 
     ev = new lr.EventView({ 
      model: e, 
      parentView = that 
     }); 
} 

,然後訪問它像這樣:

lr.EventView = Backbone.View.extend({ 
    initialize: function() { 
     _.bindAll(this, "render"); 
     console.log(this.parentView.foo); 
    }, 
    render: function() { 
    } 
    });