2014-12-18 11 views
10

Chciałbym dodać domyślną funkcję toDisplay do wszystkich modeli, które będą używać metadanych, w przeciwieństwie do definicji atrybutów/asocjacji, do wykonywania manipulacji na atrybutach/powiązaniach instancji, dzięki czemu będą odpowiednie do wyświetlania w interfejsie użytkownika.Jak mogę dodać metodę instancji do wszystkich modeli w pliku sails.js?

na przykład:

Foo.findOne(someId) 
 
    .exec(function(err, foo) { 
 
    ... 
 
    res.view({ 
 
     foo: foo.toDisplay(), 
 
    }); 
 
    });

Tak, chciałabym dodać tę funkcję także wszystkie modele. Mogę sobie wyobrazić

Model.prototype.toDisplay = ... 

rozwiązanie, ale nie jestem pewien, gdzie można uzyskać model z (jakiegoś długo require ('waterline /..../ modelu') ścieżki?), i gdybym miał modelu, gdzie umieścić to snip-it.

Prosimy o radę.

+0

OK, zobaczmy, czy dodanie większej liczby tagów daje więcej niż 12 wyświetleń w ciągu 40 godzin (4 z nich to moje). – umassthrower

Odpowiedz

8

Konfiguracja modelu jest w pełni udokumentowana here on SailsJS.org. @umassthrower ma rację wskazując, że dodanie metody instancji do config/models.js spowoduje dodanie jej do wszystkich modeli; ma również rację, gdy obserwuje, że nie jest to zamierzone użycie pliku konfiguracyjnego.

Powodem, dla którego jest to trudniejsze w żagle niż w Railsach, jest fakt, że Ruby ma prawdziwe klasy i dziedziczenie, a JavaScript ma tylko obiekty. Jednym z dość czystych sposobów symulowania dziedziczenia i rozszerzania obiektów modelu z "podstawowego" obiektu byłoby użycie czegoś takiego jak Lodash's _.merge function. Na przykład można zapisać model bazowy w lib/BaseModel.js:

// lib/BaseModel.js 
module.exports = { 

    attributes: { 

    someAttribute: 'string', 

    someInstanceFunction: function() { 
     // do some amazing (synchronous) calculation here 
    } 

    } 

}; 

Następnie w pliku modelu, wymagają lodash i używać _.extend:

// api/models/MyModel.js 
var _ = require('lodash'); 
var BaseModel = require("../../lib/BaseModel.js"); 
module.exports = _.merge({}, BaseModel, { 

    attributes: { 

    someOtherAttribute: 'integer' 

    } 

}; 

Atrybuty od modelu bazowego zostaną połączone z MyModel z MyModel pierwszeństwo.

Ustawienie pierwszego argumentu pustego modelu {} jest tutaj ważne; _.merge jest destrukcyjny dla pierwszego przesłanego obiektu, więc jeśli zrobiłeś tylko _.merge(BaseModel, {...}, model podstawowy byłby modyfikowany.

Pamiętaj też o npm install lodash!

+0

To wydaje się rozsądne podejście i bardziej smaczne niż dodanie ich do config/models.js. Nadal będę musiał dodać dodatkową linię do każdego modelu, ale przynajmniej tylko raz, a następnie będę mieć tę strukturę na miejscu. Spróbuję, dzięki! – umassthrower

+0

Zgodnie z oczekiwaniami to działa. Dzięki. – umassthrower

+0

Jestem leniwym facetem i jeśli chcę dodać coś do każdego modelu, zmuszenie mnie do dodania tej samej linii do każdego pliku modelu naprawdę mnie denerwuje. -1 - dla mnie to nie jest odpowiedź na pytanie - nadal musisz coś zrobić z każdym modelem. – pie6k

-2

Można to zrobić dodając swoją funkcję do modelu atrybutów, tak jak poniżej:

module.exports = { 
    attributes: { 
     attribute1: { 
      type: String 
     }, 
     attribute2: { 
      type: String 
     }, 
     toDisplay: function() { 
      // your function here 
     } 

     // You can also override model functions like .toJSON or .toObject 
     toJSON: function() { 
      // your custom JSON here 
     } 
    } 
} 

Jest więcej informacji w Sails documentation for models pod Metod atrybut. Warto zauważyć, że w zależności od tego, co robisz, możesz w ogóle nie potrzebować metody toDisplay(); możesz tylko przesłonić metodę toJSON(), jeśli próbujesz tylko sformatować dane wyjściowe lub usunąć poufne informacje.

+0

Już to mam, problemem jest umieszczanie go na każdym module. Z całą pewnością można to zrobić i jestem pewien, że mogłem wymyślić sposób, w jaki nie można go ulepszać, poprzez wbicie się w jądro linii wodnej i rozszerzenie prototypu czegoś tam, ale miałem nadzieję, że będzie bardziej usankcjonowany sposób robienia tego. Tak myślę, że mówisz, to nie jest obsługiwane w żaden standardowy sposób w v0.10, więc sam muszę to rozgryźć. – umassthrower

+0

Przeczytałem wszystkie dokumenty i przejrzałem kod linii wodnej, gdzie domyślne metody zostały dodane do Modelu: https://github.com/balderdashy/waterline/tree/master/lib/waterline/model/lib/defaultMethods i https://github.com/balderdashy/waterline/blob/master/lib/waterline/model/index.js – umassthrower

+0

@umassthrower Ohhhh, źle zrozumiałem. Próbujesz umieścić go na każdym module, a nie na jednym modelu ..... hmm. Właściwie to dobre pytanie. Mój błąd. –