2016-09-21 40 views
6

'da ES6'da tanımladığı bir sınıf içinde bir yöntem çağrılamıyor Node.js, Express.js ve MongoDB kullanarak bir uygulama yapıyorum. Bir MVC kalıbı kullanıyorum ve ayrıca rotalar için ayrı bir dosyam var. Bir yöntemin içinde bildirilen başka bir yöntemi çağırdığı bir Denetçi sınıfı oluşturmaya çalışıyorum. Fakat bunu yapamam mümkün görünmüyor. "Tanımlanamayan mülkünü okuyamaz" ı alıyorum. Kendi kendine giden bu kodu yayınlanıyorduysaNode.js

Cannot read property 'callme' of undefined 

:

index.js ben hata mesajı aşağıdaki olsun bu çalıştırdığınızda

let express = require('express'); 
let app = express(); 

let productController = require('../controllers/ProductController'); 

app.post('/product', productController.create); 

http.createServer(app).listen('3000'); 

ProductController.js

class ProductController { 
    constructor(){} 

    create(){ 
    console.log('Checking if the following logs:'); 
    this.callme(); 
    } 

callme(){ 
    console.log('yes'); 
} 
} 
module.exports = new ProductController(); 

dosya dosya aşağıdaki gibi küçük bir değişiklik ile ve çalışır.

class ProductController { 
    constructor(){} 
    create(){ 
    console.log('Checking if the following logs:'); 
    this.callme(); 
    } 

    callme(){ 
    console.log('yes'); 
    } 
} 
let product = new ProductController(); 
product.create(); 

Neden biri çalışıyor, diğeri değil? YARDIM!

+2

Bunu [Bir sınıf örneği dışa asla Burada sorunu gösteren basit bir örnek ] (http://stackoverflow.com/a/39079929/1048572). Sınıfı kendiniz dışa aktarın veya yalnızca bir nesneyi kullanın. – Bergi

cevap

2

Yöntemin being rebound to the Layer class within express ise, kendi özgün bağlamı kaybetmeden. ifade yolları kolları yolu kendisine rota geri arama atayan bir Layer sınıfında, her birini sarma gereğidir:

senin sorunlar ortaya nerede
this.handle = fn; 

, bu atama otomatik Layer işlev bağlamı rebinds.

function Example() { 
    this.message = "I have my own scope"; 
} 
Example.prototype.logThis = function() { 
    console.log(this); 
} 

function ReassignedScope(logThisFn) { 
    this.message = "This is my scope now"; 
    // simulation of what is happening within Express's Layer 
    this.logThis = logThisFn; 
} 

let example = new Example() 
let scopeProblem = new ReassignedScope(example.logThis); 

scopeProblem.logThis(); // This is my scope now 

Diğerleri zaten açıkça ProductController örneğine yönteminizi bağlamak için çözüm, dikkat çekmişlerdir :

app.post('/product', productController.create.bind(productController)); 
2

create yöntemini yöntem olarak geçirdiğinizde, muhtemelen beklediğiniz gibi farklı bağlamda (this) çağrılır. Bunu bağlayabilir:

app.post('/product', productController.create.bind(productController)); 

this nesneyi düzeltmek anlamına gelir sağlamak için başka kaç yolu vardır.

E.g. fonksiyonu (ok veya klasik olarak) ile sarın:

app.post('/product', (...args) => productController.create(...args)); 

Veya bağlama yöntemleri yapıcısındaki:

constructor() { 
    this.create = this.create.bind(this); 
}