Reputation: 4671
What I'm looking for is to learn a proper way to build a webapp
. I already built some things, but I've got to a point where I need to reuse some data and with ng-controllers
, it's getting harder.
I already know controllers
are not the best option, so I tried to jump to directives
, based on some articles I've read. But none of them has helped me.
So, let me try to describe it.
I'm building a dashboard
, where i have some clients (add/edit/del), projects (which invole one or more clients), agenda, configuration, financials, etc..
I've built a lot of things already, but for example:
On the home page I'm displaying a table with the last 5 clients added to the app
, also a table with the last 5 projects added to the app. Then, on the clients.html
page, I display the whole table, same goes for projects, on the project.html
. Both with just 3-4 fields with name, tel and email. Then on the individual client page, i display the whole information about that client. Such as address, email, contacts, observations, etc. And also a list of projects he is involved.
So what I have is something like this:
app.js
myApp.controller('ClientesCtrl', function ($scope, $http, $routeParams) {
$scope.pagename = "Clientes";
$scope.get_cliente = function() { //Function - Get Cliente
$http.get("scripts/data/clientes.json")
.success( function(data) {
$scope.pagedClientes = data;
})
.error(function(data) {});
};
$scope.add_cliente = function() { //Function - Add Cliente
$scope.formprevent = true;
$http.post('scripts/php/db.php?action=add_cliente',
{
'cod': $scope.cad.cod,
[... more data ...]
}
)
.success(function (data, status, headers, config) {})
.error(function (data, status, headers, config) {});
};
});
Same goes for projects, each one with it's controller.
My folder/File organizations is very very simple (since I don't know what I can put in different files, or even how to call it back). It's something like this:
-index.html
-scripts
--js
---angular.min.js
---angular-route.min.js
--app
---app.js
-content
--home.html
--clients.html
--projects.html
The problem starts when i need to show those data in a lot of pages.
For example in the home page, i have a list with a resume of the main data, such as total clients, total projects, and it's like this:
<div class="col-md-3" ng-controller="ClientesCtrl">
<div ng-init="get_cliente();>
<div class="label">{{pagedClientes.length || "00"}}</div>
<div class="text">clientes totais</div>
</div>
</div>
<div class="col-md-3" ng-controller="ProjectsCtrl">
<div ng-init="get_projects()">
<div class="label">{{pagedProjects.length || "00"}}</div>
<div class="text">Processos totais</div>
</div>
</div>
<div class="col-md-3">
<div>
<div class="label">00</div>
<div class="text">Processos abertos</div>
</div>
</div>
<div class="col-md-3">
<div>
<div class="label">00</div>
<div class="text">Compromissos abertos</div>
</div>
</div>
<div class="table-body" ng-controller="ClientesCtrl">
<table ng-init="get_clients()">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Options</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="client in pagedClients | limitTo:-5 | orderBy:'-id'" ng-if="pagedClients.length > 0">
<td>{{cliente.cod}}</td>
<td>{{cliente.nm_client}}</td>
<td>
<a class="bt-t bt-inf" href="#/detcliente/{{cliente.id}}"></a>
</td>
</tr>
<tr ng-if="pagedClientes.length == 0">
<td colspan="3"><h3>No client</h3></td>
</tr>
</tbody>
</table>
</div>
<div class="table-body" ng-controller="ProjectsCtrl">
<table ng-init="get_projects()">
<thead>
<tr>
<th>ID</th>
<th>Project</th>
<th>Options</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="project in pagedProjects | limitTo:-5 | orderBy:'-id'" ng-if="pagedProjects.length > 0">
<td>{{project.cod}}</td>
<td>{{project.nm_cliente}}</td>
<td>
<a class="bt-t bt-inf" href="#/detproject/{{project.id}}"></a>
</td>
</tr>
<tr ng-if="pagedClientes.length == 0">
<td colspan="3"><h3>No project</h3></td>
</tr>
</tbody>
</table>
</div>
So, basically, I need to add the controller
in each block I need to display that data, also I have to 'init' the function to get the data again. This is a simple example, but I think it was enough to show what I need to solve.
It's worse when I need to show the individual client, with only their projects. So before I get crazy with all of those controllers, I want to know how is the best way to put up the logic, the folder/file organization, the code organization. Is it better to use a directive? to make the directive call a controller? Call multiple controllers? Or what?
Upvotes: 0
Views: 91
Reputation: 641
You need to use services to fetch the data: https://docs.angularjs.org/guide/services. For your code it would look something like this:
app.factory('clients', function ($http) {
var getClients = function() { //Function - Get Cliente
return $http.get("scripts/data/clientes.json")
.success( function(data) {
return data;
})
.error(function(data) {});
};
var add_cliente = function(cad) { //Function - Add Cliente
$http.post('scripts/php/db.php?action=add_cliente',
{
'cod': cad.cod,
[... more data ...]
}
)
.success(function (data, status, headers, config) {})
.error(function (data, status, headers, config) {});
};
return {
getClients: getClients,
add_cliente: add_cliente
}
})
You can then inject the service in a controller and use the functions in your controller:
app.controller('Ctrl', function (clients, $scope) {
clients.getClients().then(function (data) {
$scope.myClients = data;
});
});
Upvotes: 2
Reputation: 3104
Read the client data on initialization of the controller - not need to use a ng-init
.
myApp.controller('ClientesCtrl', function ($scope, $http, $routeParams) {
$scope.pagename = "Clientes";
$http.get("scripts/data/clientes.json")
.success( function(data) {
$scope.pagedClientes = data;
})
.error(function(data) {});
$scope.add_cliente = function() { //Function - Add Cliente
$scope.formprevent = true;
$http.post('scripts/php/db.php?action=add_cliente',
{
'cod': $scope.cad.cod,
[... more data ...]
}
)
.success(function (data, status, headers, config) {})
.error(function (data, status, headers, config) {});
};
});
Controllers can be nested. Define the controller on a div which wraps the area where you need the client data. Same for the ProjectsController. You could even merge the 2 controllers in one.
<div ng-controller="ClientesCtrl">
<div class="col-md-3" >
<div ng-init="get_cliente();>
<div class="label">{{pagedClientes.length || "00"}}</div>
<div class="text">clientes totais</div>
</div>
</div>
....
Upvotes: 0