2016-09-21 22 views
6

Node.js、Express.js、およびMongoDBを使用してアプリケーションを作成しています。 私はMVCパターンを使用しており、ルート用に別々のファイルも持っています。 私はControllerクラスを作成しようとしています。Controllerクラス内で宣言された別のメソッドがメソッドから呼び出されています。しかし、私はこれを行うことができないようです。私は "未定義の"プロパティを読むことができません "を取得します。私は自分自身でこのコードを実行しているNode.jsのES6で定義したクラス内のメソッドを呼び出せません

Cannot read property 'callme' of undefined 

index.jsは、私がこれを実行すると、私は、次のエラーメッセージが表示されます

class ProductController { 
    constructor(){} 

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

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

ファイル

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'); 
    } 
} 
let product = new ProductController(); 
product.create(); 

なぜ、1つはうまくいくのですか? HELP!

+2

をあなたは[クラスのインスタンスをエクスポートすることはありません](http://stackoverflow.com/a/39079929/1048572)。クラス自体をエクスポートするか、オブジェクトのみを使用します。 – Bergi

答えて

2

あなたの方法は、元のコンテキストを失う、being rebound to the Layer class within expressです。発現は、ルートを処理する方法は、それ自体にルートコールバックを割り当てLayerクラスにそれぞれを包むことによってである:

this.handle = fn; 

あなたの問題が発生する場合で、この割り当ては、自動的Layerに機能コンテキストを再バインド。ここでは、問題を実証する簡単な例です:

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 

その他が既に明示的ProductControllerインスタンスにあなたの方法をバインドすることで解決、指摘している:

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

createメソッドをメソッドとして渡すと、おそらく異なるコンテキスト(this)で呼び出されます。あなたはそれをバインドすることができます。

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

thisがオブジェクトを修正するために参照することを確認するにはどのように他の多くの方法があります。

など。コンストラクタで

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

またはBIND方法:機能(矢印や古典のいずれか)とそれを包む

constructor() { 
    this.create = this.create.bind(this); 
} 
関連する問題