Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Angular's Models Conform to the M in MVC Just Fine

DZone's Guide to

Angular's Models Conform to the M in MVC Just Fine

You should be able to attach two views to the same model (directly or indirectly) and it should just work. Consequently, either view can update the model, with changes appearing in the other view automatically. You should also be able to compose models from other models, and that should just work too. So, let's see...

· Web Dev Zone ·
Free Resource

Learn how error monitoring with Sentry closes the gap between the product team and your customers. With Sentry, you can focus on what you do best: building and scaling software that makes your users’ lives better.

Note: MVC in this context is a 1978 design pattern, not an ASP.NET related technology that Microsoft released in 2007.

Models in MVC

You should be able to attach two views to the same model (directly or indirectly) and it should just work. Consequently, either view can update the model, with changes appearing in the other view automatically. You should also be able to compose models from other models, and that should just work too.

Angular’s Conformance

I’m only testing Angular 1.5 here (not 2.0.0-beta.x or above), but yet it works as expected.

Take a look at the running application: paulhammant.com/demos/angulars-model-conforms-to-the-m-in-mvc/index.html

Screenshot: Click to see the interactive iframe version

Expand one of the expandable items and click on the number of calories for the item. You can now edit that (span becomes an input). Note that changes you make impact the other tree-table. If you scroll down, the change is also apparent in the underpinning models. Therefore, M, V, and C behave as you’d expect.

Note that I’m composing models, and Angular knows what’s connected to what (see source links below).

Source

To view the 73-line source of that page go to paulhammant.com/demos/angulars-model-conforms-to-the-m-in-mvc/index.html and right click to "view source".

Or, take a look at the 58-line JavaScript source for the Angular controller logic

angular.module('project', ['ngResource'])
    .factory('JsonGetter', function ($resource) {
        var JsonGetter = $resource(':q');
        return JsonGetter;
    })
    .controller('TheController', function ($scope, JsonGetter) {
        function insertItems(toIterateOver, type, plural, verb) {
            verb = verb || "consumed";
            plural = plural || "items";
            angular.forEach(toIterateOver, function (date) {
                if (!(date.when in $scope.datesThenMealsOrExercise)) {
                    $scope.datesThenMealsOrExercise[date.when] = [];
                }
                arr = $scope.datesThenMealsOrExercise[date.when];
                arr.push({
                    type: type,
                    plural: plural,
                    verb: verb,
                    name: date.name,
                    items: date.items
                });
            });
        }

        JsonGetter.get({q:'my-data.json'}, function(mne) {
            $scope.mealsAndExercise = mne; // raw
            // Marginally trasnformed for first view
            $scope.mealsOrExerciseThenDates = [
              {
                name:"Meals",
                plural:"items",
                verb:"consumed",
                data: mne.M
              },
              {
                name:"Exercise",
                plural:"exercises",
                verb:"burned",
                data: mne.E
              }
            ];
            $scope.datesThenMealsOrExercise = {};
            // Transformed quite a bit for second view
            insertItems(mne.M, "Meal", "items", "consumed");
            insertItems(mne.E, "Exercise", "exercises", "burned");
        });
        $scope.totCalories = function(toTotal){
            var totalKCal = 0;
            for(var i = 0; i < toTotal.length; i++){
                var item = toTotal[i];
                totalKCal += item.kcal;
            }
            return totalKCal;
        };
        $scope.abs = function(toAbs){
            return Math.abs(toAbs);
        }
    });

Or, take a look at the JSON it loads over HTTP

{
  "goal" : 1300,
  "M": [
    {
      "when": "2016-02-25",
      "name" : "snack",
      "items": [{
        "item": "Snickers bar", "kcal": 305
      }]
    },
    {
    "when": "2016-02-26",
    "name" : "Breakfast",
    "items": [
      {
        "item": "Nachos", "kcal": 223
      },{
        "item": "Dip", "kcal": 371
      },{
        "item": "Salsa", "kcal": 188        
    }]
  },
  {
    "when": "2016-02-26",
    "name" : "Lunch",
    "items": [{
      "item": "Steak", "kcal": 498
    },{
      "item": "Mash", "kcal": 212
    }]
  }
  ],
  "E": [
  {
    "when": "2016-02-26",
    "name" : "Gym",
    "items": [{
      "item": "Running Machine", "kcal": -210
    },{
      "item": "Step Machine", "kcal": -88
    },{
      "item": "Weights", "kcal": -80
    }]
  },
    {
      "when": "2016-02-25",
      "name" : "Swim",
      "items": [{
        "item": "42 laps", "kcal": -305
      }]
    }
  ]
}

Selling a Style of Angular

When I code Angular for demo purposes, I completely avoid:

  1. Any build technology
  2. HTML inside JavaScript (template style)
  3. JsFiddle-like services

I wish more people would too. It’s much easier to pick up or teach. Especially, if you are example-oriented like me.

What’s the best way to boost the efficiency of your product team and ship with confidence? Check out this ebook to learn how Sentry's real-time error monitoring helps developers stay in their workflow to fix bugs before the user even knows there’s a problem.

Topics:
angular ,mvc

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}