12

Node.js、Express.js、MongoDB を使ってアプリを作っています。私は MVC パターンを使用しており、ルート用に別のファイルもあります。メソッドがその中で宣言された別のメソッドを呼び出すコントローラークラスを作成しようとしています。しかし、私はこれを行うことができないようです。「未定義のプロパティ '' を読み取れません」というメッセージが表示されます。

index.js ファイル

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();

これを実行すると、次のエラー メッセージが表示されます。

Cannot read property 'callme' of undefined

次のように少し変更して、このコードを単独で実行しましたが、動作します。

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

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

一方が機能し、もう一方が機能しないのはなぜですか? ヘルプ!

4

2 に答える 2

5

メソッドはexpress 内のクラスに再バインドされておりLayer、元のコンテキストが失われています。LayerExpress がルートを処理する方法は、ルート コールバックをそれ自体に割り当てるクラスで各ルートをラップすることです。

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));
于 2016-09-21T16:53:30.713 に答える