webentwicklung-frage-antwort-db.com.de

sails.js Zugriff auf Controller-Methode von Controller-Methode

Wie kommt es, dass Sie nicht auf andere Controller-Methoden von einem anderen aus zugreifen können? 

so was.

module.exports = 

   findStore: ->
       # do somthing

   index: ->
      @findStore(); # Error: undefined

Zusammengestellt

module.exports = {
  findStore: function() {},
  index: function() {
    return this.findStore(); // Error: undefined
  }
};

Wenn Sie das nicht können, warum dann nicht? wie soll ich das sonst machen ...

15
iConnor

Das gleiche Problem in den letzten Stunden haben. Ich habe den Ordner api/services verwendet. Möglicherweise ist es nicht genau das, was Sie brauchen, aber es ist eine Option. Eine gute Erklärung ist hier. Welche Dienste würde man zum Ordner api/services in sails.js hinzufügen

7
lloop

Sie können sails.controllers.yourControllerName.findStore() verwenden.

das globale Objekt sails weist auf fast alles hin.

64
nidheeshdas

Eine der besten Möglichkeiten, Ihren Code in Sails zu organisieren, zumindest für mich und mein Team, bestand darin, über die gesamte Geschäftslogik in Services (/ api/services) zu verfügen. Auf diese Objekte kann von jedem Controller aus global zugegriffen werden.

Außerdem ist es eine gute Praxis, mit Versprechen in Diensten zu arbeiten (da Sails sie für die Modellmethoden verwendet).

Erstellen Sie einfach einen Store-Service (StoreService.js) mit Ihrem Code:

module.exports = {
  findStore: function(storeId) {
    // here you call your models, add object security validation, etc...
    return Store.findOne(storeId);
  }
};

Ihre Controller sollten sich um alles kümmern, was mit Anfragen, Anrufdiensten und der Rückgabe entsprechender Antworten zusammenhängt.

In Ihrem Beispiel könnte der Controller beispielsweise Folgendes aufweisen:

module.exports = {
  index: function(req, res) {
    if(req.param('id')) {
      StoreService.findStore(req.param('id'))
        .then(res.ok)
        .catch(res.serverError);
    } else {
      res.badRequest('Missing Store id');
    }
  },
  findStore: function(req, res) {
    if(req.param('id')) {
      StoreService.findStore(req.param('id'))
        .then(res.ok)
        .catch(res.serverError);
    } else {
      res.badRequest('Missing Store id');
    }
  },
};

Auf diese Weise haben Sie wirklich einfache Steuerungen, und die gesamte Geschäftslogik wird von Diensten verwaltet.

24

Es ist etwas ärgerlich, wenn Sie nur versuchen, schnell etwas aufzubauen, aber auf lange Sicht zwingt dies zu einer guten Code-Organisationspraxis (indem es schwieriger wird, die gesamte Geschäftslogik in einen Controller zu stecken).

2
Josh Liptzin

Ich möchte eine Lösung vorschlagen, die funktioniert, aber nicht die bestmögliche Lösung. Wir können die Bindungsfunktion verwenden, um den Kontext mit der aufrufenden Quelle zu verbinden, wie unten gezeigt:

generateUrl ist im Controller A vorhanden

function generateUrl(){
  return 'www.google.com';
}

get URL ist eine andere Methode in Controller A

getURL(){
  A.generateURL.bind(A.generateURL) //func call with optional arg
}

Ich hoffe das hilft!

1
monothorn

Eine elegantere Methode zur Lösung dieses Problems ist die Verwendung des Schlüsselworts this vor dem Funktionsnamen.

Beispiel: 

one: function() {
   console.log('First Function');
},

two: function() {
   // call the function one in the same controller
   this.one();
}
0
Marcos Mendes

Sie können so etwas tun:

//ArticleController
module.exports = {
  findStore: async () => {
    return await findStoreFunc(req.param('id'));
  },
  index: async () => {
    ...
    return await findStoreFunc(id);
  }
};

const findStoreFunc = async (id) => {...}

Und um die Funktion von einem anderen Controller zu verwenden:

const ArticleController = require('./ArticleController');
//CustomerController
module.exports = {
  index: async () => {
    ...
    let article = await ArticleController.findStore(id);
    ...
  }
};
0
Marcell