2015-05-07 2 views
1

Я использую REST API, используя узел с hapijs. Итак, я должен использовать наследования, и у меня нет успеха в доступе к функциям отца. У меня есть это:Node.js наследует

controller.js

var __ = require('underscore'); 

var Controller = function(){ 
    var Validator = require('../validators/'+this.controller); 
    Controller.prototype.validate = new Validator(); 
} 

Controller.prototype.returnErrors = function(err){ 
    var errors = []; 
    __.each(err, function(error){ 
     errors.push(error.message); 
    }); 
    return errors; 
} 

module.exports = Controller; 

reckon.js

var __ = require('underscore'), 
    reckon = require('../components/reckon'), 
    inherits = require('util').inherits, 
    Controller = require('./controller'), 
    Reckon = require('../models/reckon').Reckon; 

var ReckonCtr = function() { 
    this.controller = "reckon"; 
    ReckonCtr.super_.call(this); 
} 

inherits(ReckonCtr, Controller); 

ReckonCtr.prototype.get = function (request, reply, server, callback) { 
    this.validate.get(__.extend({company:request.params.company}, request.query), function(validation, value){ 
     if(validation.error){ 
      return callback(this.returnErrors(validation.error.details)); 
     } 
     reckon.getReckon(request.params.company, request.query, function(error, success){ 
      if(error) return callback(error); 

      return callback(null, success); 
     }); 
    }); 
} 
module.exports = new ReckonCtr(); 

Почему я могу получить доступ к "this.validate" и не может "this.returnErrors"? (TypeError: Uncaught error: Объект # не имеет метода 'returnErrors').

А как насчет возврата моего возврата?

Заранее благодарен

ответ

3

Это проблема определения проблемы.

Вы можете получить доступ к this.validate, поскольку вы находитесь в контексте метода ReckonCtr.prototype.get, в котором this ссылается на экземпляр. Однако при попытке доступа к this.returnErrors вы находитесь в контексте обратного вызова this.validate.get, где this больше не указывает на экземпляр.

Простейший, наиболее распространенный способ решения этой проблемы - взять ссылку на как локальную переменную и обратиться к переменной, а не к this непосредственно, например.

ReckonCtr.prototype.get = function (request, reply, server, callback) { 
    var self = this; 
    self.validate.get(__.extend({company:request.params.company}, request.query), function(validation, value){ 
     if(validation.error){ 
      return callback(self.returnErrors(validation.error.details)); 
     } 
     reckon.getReckon(request.params.company, request.query, function(error, success){ 
      if(error) return callback(error); 

      return callback(null, success); 
     }); 
    }); 
} 
+0

А как насчет поворота «частной» моей функции возврата? Добавить символ подчеркивания и заблокировать доступ к функциям «_» в файле маршрутов? –

+0

@PopoKakedo Вы имеете в виду сделать 'returnErrors' доступным только из' ReckonCtr'? Есть много способов сделать это, если вы можете предоставить немного больше контекста, я мог бы, вероятно, дать вам лучший ответ. – James

2

this.validate используется в контексте, где this относится к ReckonCtr объекта, так это работает. В обратном вызове this не относится к ReckonCtr.

Замешательство над what exactly this refers to in a given context - большая проблема в JavaScript. Существует несколько решений. Этот список не является, без сомнения, неполно:

  • В функции, которая содержит функцию обратного вызова, сохранить ссылку на this с чем-то вроде var self = this;, а затем использовать self в функции обратного вызова, а не this.
  • Если вы используете последнюю версию узла, вы можете использовать синтаксис сильной стрелки, чтобы сделать this более предсказуемым.
  • Используйте bind(), call() или apply(), чтобы явно установить значение this.
  • Если объект, который вы хотите, является одноэлементным, просто используйте объект явно, а не this.
Смежные вопросы