Quale è considerato migliore:
- avere una direttiva che interagisce direttamente con i servizi
o
- avere una direttiva che espone determinati hook a cui il responsabile del trattamento può vincolare il comportamento (che coinvolge servizi)?
Quale è considerato migliore:
o
Risposte:
Una direttiva è la migliore (come regola empirica) quando è breve (dal punto di vista del codice), (potenzialmente) riutilizzabile e ha un ambito limitato in termini di funzionalità. Fare una direttiva che include l'interfaccia utente e dipende da un servizio (che presumo gestisce la connessione al back-end), non solo gli dà 2 ruoli funzionali, vale a dire:
ma anche renderlo meno riutilizzabile, poiché non è possibile riutilizzarlo con un altro servizio o con un'interfaccia utente diversa (almeno non facilmente).
Quando prendo queste decisioni, spesso confronto con gli elementi HTML incorporati: ad esempio <input>
, <textarea>
oppure <form>
: sono completamente indipendenti da qualsiasi backend specifico. HTML5 ha fornito <input>
all'elemento alcuni tipi extra, ad esempio date
, che è ancora indipendente dal back-end, e dove vanno esattamente i dati o come vengono utilizzati. Sono puramente elementi di interfaccia. I tuoi widget personalizzati, costruiti usando le direttive, penso che dovrebbero seguire lo stesso schema, se possibile.
Tuttavia, questa non è la fine della storia. Andando oltre l'analogia con gli elementi HTML incorporati, puoi creare direttive riutilizzabili che chiamano entrambi i servizi e utilizzare una direttiva puramente UI, proprio come potrebbe usare a <textarea>
. Supponi di voler utilizzare un po 'di HTML nel modo seguente:
<document document-url="'documents/3345.html'">
<document-data></document-data>
<comments></comments>
<comment-entry></comment-entry>
</document>
Per codificare la commentEntry
direttiva, è possibile creare una direttiva molto piccola che contenga solo il controller che collega un servizio con un widget UI. Qualcosa di simile a:
app.directive('commentEntry', function (myService) {
return {
restrict: 'E',
template: '<comment-widget on-save="save(data)" on-cancel="cancel()"></comment-widget>',
require: '^document',
link: function (scope, iElement, iAttrs, documentController) {
// Allow the controller here to access the document controller
scope.documentController = documentController;
},
controller: function ($scope) {
$scope.save = function (data) {
// Assuming the document controller exposes a function "getUrl"
var url = $scope.documentController.getUrl();
myService.saveComments(url, data).then(function (result) {
// Do something
});
};
}
};
});
Portandolo all'estremo, potresti non aver mai bisogno di avere un ng-controller
attributo manuale nell'HTML: puoi fare tutto usando le direttive, purché ognuna abbia direttamente un ruolo "UI" chiaro o un ruolo "dati" chiaro.
C'è un aspetto negativo che dovrei menzionare: dà più "parti mobili" all'applicazione, il che aggiunge un po 'di complessità. Tuttavia, se ogni parte ha un ruolo chiaro ed è buona (unità + E2E testata), direi che ne vale la pena e un vantaggio complessivo a lungo termine.
Consentitemi di non essere d'accordo con la risposta di Michal Charemza.
Sebbene la sua risposta sia teoricamente corretta, non è molto pratica per il mondo reale.
Lo dico perché pensavo in quel modo e cercavo di applicarlo su una grande app del mondo reale che io e il mio team stiamo costruendo ed è diventato troppo problematico.
L'analogia con il linguaggio HTML non è buona, perché non dovresti sforzarti di costruire direttive generiche, estremamente riutilizzabili, perché non stai costruendo un'applicazione generica come un browser web.
Invece, dovresti usare le direttive per creare un DSL (Domain Specific Language) per la tua app, che risiede sul proprio dominio.
Ciò non significa che tutte le direttive non debbano essere generiche. Alcuni potrebbero esserlo, se è nella loro natura. Se stai creando un selettore di date personalizzato, rendilo sicuramente generico e riutilizzabile tra le app.
Ma se stai costruendo qualcosa come una casella di accesso che si lega al tuo back-end, fallo e basta.
L'unica regola empirica dovrebbe essere: non duplicare mai il codice (piccoli pezzi astratti in fabbriche e servizi) e renderlo testabile attraverso l'iniezione di dipendenza. Fortunatamente, con Angular, questi sono un gioco da ragazzi.
Mantienilo semplice. :)
Penso che la domanda "dovrebbe una direttiva interagire con un servizio" dipende da cosa sta facendo il tuo servizio.
Ho avuto direttive che interagiscono con servizi che non fanno nulla con le richieste HTTP e penso che sia un buon modello. I servizi / le fabbriche sono ottimi per incapsulare più logica orientata ai dati e le direttive sono ottimi per incapsulare la logica orientata alla presentazione. Lo scopo dichiarato dei servizi nei documenti angolari è: "Puoi utilizzare i servizi per organizzare e condividere il codice attraverso la tua app". È piuttosto ampio, ma i servizi possono essere utilizzati per raggiungere questo obiettivo nelle direttive.
Detto questo, capisco il desiderio in alcuni casi di farlo in modo che le direttive non facciano direttamente richieste HTTP. Ancora una volta, dipende dal servizio e da come stai organizzando i tuoi servizi.
Come da framework AngularJS, dovremmo singleton fabbriche / servizi per ottenere qualsiasi dato dal server. In modo che queste fabbriche possano essere riutilizzate attraverso l'applicazione senza riscrivere le stesse. Bene, all'interno della direttiva possiamo chiamare queste fabbriche per ottenere i dati recuperati da Api / server.