Ich lese diese beiden großen Artikel:AngularJS: Wie sollten Controller und Fabriken/Services mit einem reichen, hierarchischen Objektmodell strukturiert sein?
The state of angularjs controllers von Jonathan Creamer
und
Rethinking AngularJS Controllers von Todd Motto
In diesen Artikeln werden die Autoren über die richtige Art und Weise sprechen Controller zu verwenden (was sie sind blutleere Brücken zwischen dem Blick und dem Modell) und Fabriken/Dienstleistungen (wo die Geschäftslogik wirklich leben sollte).
Das sind großartige Informationen, und ich war wirklich aufgeregt, die Controller in einem meiner Projekte zu refactoring, aber ich fand schnell, dass die in den Artikeln gezeigte Struktur bricht, wenn Sie ein reichhaltiges Objektmodell haben.
Hier ist eine kurze Zusammenfassung des Setup von "Rethinking AngularJS Controllers":
Hier ist der Controller:
app.controller('InboxCtrl', function InboxCtrl (InboxFactory) {
var vm = this;
vm.messages = InboxFactory.messages;
vm.openMessage = function (message) {
InboxFactory.openMessage(message);
};
vm.deleteMessage = function (message) {
InboxFactory.deleteMessage(message);
};
InboxFactory
.getMessages()
.then(function() {
vm.messages = InboxFactory.messages;
});
});
und hier ist die Fabrik:
app.factory('InboxFactory', function InboxFactory ($location, NotificationFactory) {
factory.messages = [];
factory.openMessage = function (message) {
$location.search('id', message.id).path('/message');
};
factory.deleteMessage = function (message) {
$http.post('/message/delete', message)
.success(function (data) {
factory.messages.splice(index, 1);
NotificationFactory.showSuccess();
})
.error(function() {
NotificationFactory.showError();
});
};
factory.getMessages = function() {
return $http.get('/messages')
.success(function (data) {
factory.messages = data;
})
.error(function() {
NotificationFactory.showError();
});
};
return factory;
});
Das ist großartig und weil providers
(die Fabrik) sind Singletons, die Daten werden über Ansichten hinweg gepflegt und können abgerufen werden, ohne sie von der API neu laden zu müssen.
Dies funktioniert problemlos , wenn messages
ein Top-Level-Objekt sind. Aber was passiert, wenn sie es nicht sind? Was ist, wenn es sich um eine App zum Durchsuchen der Posteingänge anderer Benutzer handelt? Vielleicht sind Sie ein Administrator und möchten die Posteingänge eines beliebigen Benutzers verwalten und durchsuchen können. Vielleicht brauchen Sie die Postfächer mehrerer Benutzer gleichzeitig. Wie funktioniert das? Das Problem besteht darin, dass Posteingangnachrichten in dem Dienst gespeichert sind, d. H. InboxFactory.messages
.
Was passiert, wenn die Hierarchie wie folgt aus:
Organization
|
__________________|____________________
| | |
Accounting Human Resources IT
| | |
________|_______ _____|______ ______|________
| | | | | | | | |
John Mike Sue Tom Joe Brad May Judy Jill
| | | | | | | | |
Inbox Inbox Inbox Inbox Inbox Inbox Inbox Inbox Inbox
Jetzt messages
sind mehrere Ebenen tief in der Hierarchie, und haben keine Bedeutung auf eigene Faust. Sie können keine Nachrichten in der Factory speichern, InboxFactory.messages
, da Sie Nachrichten für mehrere Benutzer gleichzeitig abrufen müssen.
Jetzt haben Sie eine OrganizationFactory, eine DepartmentFactory, eine UserFactory und eine InboxFactory. Das Abrufen von "Nachrichten" muss im Zusammenhang mit einer user
stehen, die im Zusammenhang mit einer department
steht, die im Zusammenhang mit einer organization
steht. Wie und wo sollten die Daten gespeichert werden? Wie sollte es zurückgezogen werden?
Also wie soll das gelöst werden? Wie sollten Controller, Fabriken/Services und reiche Objektmodelle strukturiert sein?
An diesem Punkt in meinem Denken, neige ich dazu, es nur schlank zu halten und kein reiches Objektmodell zu haben. Speichern Sie die Objekte einfach auf dem $ -Skope, der in den Controller injiziert wurde. Wenn Sie zu einer neuen Ansicht navigieren, laden Sie sie von der API neu. Wenn Sie müssen einige Daten über Ansichten beibehalten, können Sie diese Brücke mit einem Service oder Fabrik bauen, aber es sollte nicht die Art, wie Sie tun meisten Dinge.
Wie haben andere das gelöst? Gibt es irgendwelche Muster dafür?
Sollte dies nicht eine Aufgabe für die Back-End-Endpunkt sein? Wenn Sie also als Jonh 'GET/messages' eingeloggt sind, werden Nachrichten nur für John zurückgegeben und die Schnittstelle unterscheidet sich von der, die der Chef der Organisation sieht, wenn er eingeloggt ist. – Terafor