My previous post described the back-end configuration for my “People” domain model (people, addresses, etc.) Let’s look at how this data is used within the web application using an MVC web API controller along with an AngularJS web service call and simple data binding.
I created a very simple ApiController class, called PeopleController, to start with.
public class PeopleController : ApiController { public IEnumerable<Person> Get() { var repository = new ExampleDataRepository(); return repository.GetSomePeople(); } public Person Get(int id) { var repository = new ExampleDataRepository(); var person = repository.GetPerson(id); if (person == null) { throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound)); } return person; } }
We’ll add some more robust functionality later, but for now, this web service delivers either a list of people, or details about an individual person. The work to look up these domain entities in the database is delegated to a Repository class.
public class ExampleDataRepository { public IEnumerable<Person> GetSomePeople() { using (var ctx = new ExampleDbContext()) { return ctx.People.AsNoTracking().Take(30).ToList(); } } public Person GetPerson(int personId) { using (var ctx = new ExampleDbContext()) { return ctx .People .Include(p => p.EmailAddresses) .Include(p => p.PostalAddresses) .Include(p => p.PhoneNumbers) .AsNoTracking() .SingleOrDefault(p => p.PersonId == personId); } } }
Again, we are starting out simply at first. The GetSomePeople method returns the first 30 People records it finds. The GetPerson method returns the details of a particular person along with their associated information.
A few things to note about the preceding code are:
The listCtrl.js file contains the controller functionality for displaying the list of people returned from the web service. When the controller is instantiated, there are three AngularJS services injected into it:
angular .module('myApp.ctrl.list', []) .controller('listCtrl', ['$scope', '$http', '$location', function ($scope, $http, $location) { $scope.people = []; $scope.viewPerson = function (id) { $location.path("/detail/" + id); }; $http({ method: 'GET', url: '/api/people' }).success(function (data, status, headers, config) { $scope.people = data; }); }]);
The $http service is used to make a call to the “/api/people” web service. It returns a promise that can be used to handle the result of the service call. In our case, we just update the $scope object with the new list of people.
AngularJS uses declarative markup to define how data is bound to the view. In other words, you modify the HTML content with special tags and attributes that the AngularJS engine then interprets to dynamically update the view.
For this example, our data binding is very simple.
<tbody> <tr ng-repeat="person in people"> <td><a ng-click="viewPerson(person.personId)"><i class="icon-edit"></i></a></td> <td>{{person.title}}</td> <td>{{person.firstName}}</td> <td>{{person.middleName}}</td> <td>{{person.lastName}}</td> <td>{{person.suffix}}</td> </tr> </tbody>
This markup repeats (“ng-repeat”) a table row (“<tr>”) for each person in the people collection (which is contained in the controller’s scope object). The double-braces (“{{ … }}”) syntax is used to bind data to the view. Finally, when the user clicks (“ng-click”) on the link, the viewPerson method is called on the scope, which in turns navigates to the person detail view.
For the detail view, the controller is similar to the list view controller.
angular .module('myApp.ctrl.detail', []) .controller('detailCtrl', ['$scope', '$http', '$routeParams', '$location', function ($scope, $http, $routeParams, $location) { $scope.person = { title: '', firstName: '', middleName: '', lastName: '', suffix: '' }; $scope.returnToList = function () { $location.path("/"); }; $http({ method: 'GET', url: '/api/people/' + $routeParams.id }).success(function (data, status, headers, config) { $scope.person = data; }); }]);
In this case, however, a call to the web service requires the id of the person to fetch. Therefore an additional service, $routeParams, is injected into the controller that can be used to obtain parameters associated with the route itself. Notice that the details route includes an “:id” parameter.
$routeProvider.when('/detail/:id', { templateUrl: '/Home/Detail', controller: 'detailCtrl', });
This parameter is added as a property of the $routeParams service and is used to modify the web service call.
The details view itself uses standard HTML input controls to display the person’s details.
Note that the input controls use the data-ng-model attributes (“data-ng-model” and “ng-model” are the same – it just depends if you want to use more strict HTML5 attributes). This incorporates two-way binding between the model contained within the controller’s scope and the HTML input controls. In other words, a change in the model will be reflected in the input control, and a change on the input control will be reflected in the model.
This example, of course, is only a simple read-only view of the people data. What’s more interesting is to incorporate additional interactive user interface elements, including displaying the data within a grid, editing people information, performing validation, etc. So, more to come …
Cloud management is difficult to do manually, especially if you work with multiple cloud…
Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…
https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…
FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…
Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…
In the intricate landscape of modern business, compliance is both a cornerstone of operational integrity…