2013-08-18 7 views
17

Przy każdym oprogramowaniu pośredniczącym Express przekazuje obiekty res i req. Obiekty te rozszerzają natywne, które pochodzą odpowiednio z http.ServerResponse i . Chciałbym wiedzieć, czy można przesłonić lub rozszerzyć metody obiektu odpowiedzi.W programach Express i Node.js możliwe jest rozszerzanie lub zastępowanie metod obiektu odpowiedzi?

Na przykład zamiast res.render('home', jsonData);, chciałbym przedłużyć res za pomocą niestandardowej metody o nazwie customRender i używać go w następujący sposób: res.customRender().

Nie utknąłem w konkretnym problemie ani nic. Chciałbym nauczyć się jak rozszerzać rodzime obiekty lub, tak jak w tym przypadku, obiekt pochodzący z zewnętrznych modułów w Node.js

Odpowiedz

28

Najlepszym pomysłem byłoby dodać niestandardową metodę do prototypu obiektu odpowiedzi:

var express = require("express"); 

express.response.customRender = function() { 
    // your stuff goes here 
}; 

I ta funkcja powinna być dostępna dla każdego res obiektu.

Możesz przeczytać kod źródłowy, aby zobaczyć, jak rozszerza on obiekty natywne. Zasadniczo robią prototyp łańcuchowym:

ekspresowych/lib/response.js

var res = module.exports = { 
    __proto__: http.ServerResponse.prototype 
}; 

I cel ten staje się prototypem newely utworzonego obiektu odpowiedzi (która pochodzi z connect ram):

res.__proto__ = app.response; 

(app.response to tylko alias do res zdefiniowany powyżej). Zauważ, że właściwość __proto__ jest odwołaniem do prototypu obiektu.

Ostrzegam jednak. Przede wszystkim __proto__ nie jest częścią EcmaScript (może nie być dostępny w innych implementacjach JavaScript). Po drugie: normalnie zrobiłbyś dziedziczenie z Object.create (ustawienie __proto__ bezpośrednio na obiekcie jest łataniem małpy i ogólnie jest złą praktyką, może złamać wiele rzeczy). Przeczytaj więcej na ten temat:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain

+0

to nie działa. z wewnątrz wywoływanego kontekstu 'this' będzie wyeksportowaną funkcją zamiast obiektu' response'. – r3wt

+0

Możesz również rozszerzyć konstrukcje ekspresowej instancji w ten sam sposób (zamiast ekspresowego konstruktora). np. var app = express(); app.response.foo = function() {console.log ('foo');} – Porlune

9

Po prostu dodaj oprogramowanie pośrednie, które dodaje funkcję customRender do rozdzielczości.

function(req, res, next) { 
    res.customRender = function() { 
    // implement your custom renderer 
    } 
    next(); 
} 
+0

Cool. Dzięki! Czy wiesz, w jaki sposób Express rozszerza funkcjonalność natywnych klas http? –

+11

Spowoduje to utworzenie nowej funkcji dla każdej odpowiedzi, lepiej jest użyć 'util.inherits' i dodać go do prototypu. –

+2

Lub przypisz funkcję do zmiennej i przypisz res.customRenger = fn; (lub zawijanie połączenia, jeśli potrzebujesz req, res, następna) – JakubKnejzlik