<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-route.js"></script>
<script src="model.js"></script>
<script src="model-service.js"></script>
<script src="app.js"></script>
<script src="app-controllers.js"></script>
<script src="company-factory.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body ng-app="ModelDemo" class="container">
<h1 class="page-header">Company Utility</h1>
<div>
<a href="#/list" class="btn btn-default">List</a>
<a href="#/crm" class="btn btn-primary">CRM</a>
<a ng-click="listPlus = !listPlus" class="btn btn-info">Toggle List Plus</a>
</div>
<hr />
<div ng-view></div>
</body>
</html>
# Demonstration of a model layer in angular
var baseModel = angular.module('baseModel', []);
// company prototype
baseModel.constant('BaseCompany', function() {
this.count = 0;
this.add = function() {
return this.count++;
};
this.subtract = function() {
return this.count--;
};
});
baseModel.service('Company', function() {
return function(data) {
angular.extend(this, data);
}
});
// company mixin with CRM functionality
baseModel.constant('CompanyCRMVisitor', {
CRM: true,
addToCRM: function() {
this.inCRM = true;
},
removeFromCRM: function() {
this.inCRM = false;
}
});
// company mixin with List plus functionality
baseModel.service('CompanyPlusVisitor', function($http, $rootScope) {
this.plus = true;
this.getText = function(company) {
$http.get('http://baconipsum.com/api/?type=meat-and-filler')
.then(function(resp) {
company.text = resp.data.pop();
});
};
this.saveCompany = function(company) {
$http.post('http://baconipsum.com/api/?type=meat-and-filler')
.then(function() {
company.saved = true;
});
};
});
/*global angular: false, alert: false*/
var app = angular.module('ModelDemo', ['baseModel', 'ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/list', {
templateUrl: 'list.html',
controller: 'ListCtrl'
})
.when('/crm', {
templateUrl: 'list-crm.html',
controller: 'CrmListCtrl'
})
.when('/company/:duns', {
templateUrl: 'company-detail.html',
controller: 'CompanyDetailCtrl',
})
.otherwise({
redirectTo: '/list'
});
});
// set global decorator
app.run(function(companyFactory, CompanyPlusVisitor, $rootScope, $route) {
$rootScope.$watch('listPlus', function (newVal) {
if (newVal) {
companyFactory.setGlobalVisitor(CompanyPlusVisitor);
}
else {
companyFactory.setGlobalVisitor({});
}
$route.reload();
})
});
[
{
"companyId":11166000000000,
"name":"FOOCO, INC.",
"duns":"001287762",
"webAddress":"http://www.www.fooico.com",
"locationType":"Headquarters",
"address":{
"address1":"700 Anderson Hill Rd",
"city":"Purchase",
"state":"NY",
"country":"United States",
"postalCode":"10577-1444",
"latitude":41.038492,
"longitude":-73.697335
},
"telePhones":[
{
"countryCode":"1",
"areaCode":"914",
"phoneNumber":"2532000"
}
],
"financials":{
"annualSales":66415.0
},
"employees":{
"employeesCount":274000,
"employeesAtThisLocationCount":1500
},
"doingBusinessAs":[
"PEPSICO ",
" PEPSICO FOODS INTERNATIONAL ",
" PEPSICO WORLDWIDE FOODS ",
" QUAKER OATS"
]
},
{
"companyId":1294131,
"name":"FOOCOLA METROPOLITAN BOTTLING COMPANY, INC.",
"duns":"001294131",
"webAddress":"www.fooico.com",
"locationType":"Headquarters",
"address":{
"address1":"1 Pepsi Way",
"city":"Somers",
"state":"NY",
"country":"United States",
"postalCode":"10589-2204",
"latitude":41.33036,
"longitude":-73.6908
},
"telePhones":[
{
"countryCode":"1",
"areaCode":"914",
"phoneNumber":"7676000"
}
],
"financials":{
"annualSales":22505.1
},
"employees":{
"employeesCount":112050,
"employeesAtThisLocationCount":5
},
"doingBusinessAs":[
"PEPSI BEVERAGES COMPANY ",
" PEPSI BOTTLING GROUP ",
" PEPSICO"
]
},
{
"companyId":7069446,
"name":"FOOI-COLA METROPOLITAN BOTTLING COMPANY INC",
"duns":"007069446",
"webAddress":"www.fooico.com",
"locationType":"Single Location",
"address":{
"address1":"3801 Brighton Blvd",
"city":"Denver",
"state":"CO",
"country":"United States",
"postalCode":"80216-3693",
"latitude":39.77356,
"longitude":-104.974938
},
"telePhones":[
{
"countryCode":"1",
"areaCode":"303",
"phoneNumber":"2929220"
}
],
"financials":{
"annualSales":52.8
},
"employees":{
"employeesCount":500,
"employeesAtThisLocationCount":500
},
"doingBusinessAs":[
"PEPSICO WEST ",
" Pepsi-Cola"
]
},
{
"companyId":885580159,
"name":"FOO-Cola Panamericana, S.R.L.",
"duns":"885580159",
"webAddress":"www.fooco.com",
"locationType":"Single Location",
"address":{
"address1":"Centro Empresarial Polar, P.H.",
"address2":"Edif. Parque Cristal, Torre Este, Piso 14",
"city":"Caracas",
"state":"Distrito Federal",
"country":"Venezuela"
},
"telePhones":[
{
"countryCode":"58",
"phoneNumber":"2122023111"
}
]
},
{
"companyId":875041857,
"name":"Foosi Cola (Bahamas) Bottling Co. Ltd.",
"duns":"875041857",
"webAddress":"www.foosi.com",
"locationType":"Single Location",
"address":{
"address1":"Prince Charles Drive",
"city":"Nassau",
"state":"New Prov",
"country":"Bahamas"
},
"telePhones":[
{
"countryCode":"1",
"areaCode":"242",
"phoneNumber":"3646666"
}
],
"employees":{
"employeesCount":90,
"employeesAtThisLocationCount":90
}
}
]
angular.module('ModelDemo').controller('ListCtrl', function ($scope, companyService) {
companyService.getList().then(function(companies) {
$scope.companies = companies;
});
});
angular.module('ModelDemo').controller('CrmListCtrl', function ($scope, companyService, CompanyCRMVisitor) {
companyService.getList(CompanyCRMVisitor).then(function(companies) {
$scope.companies = companies;
});
});
angular.module('ModelDemo').controller('CompanyDetailCtrl', function ($scope, $routeParams, companyService) {
companyService.getById($routeParams.duns).then(function (company) {
$scope.company = company;
});
});
// company service, fetch and decorate data from rest
angular.module('baseModel').service('companyService', function($http, companyFactory, $filter) {
function fetchData() {
return $http.get('data.json');
}
function getById(duns, visitor) {
return fetchData().then(function(resp) {
var company = resp.data.filter(function(c) {
return c.duns === duns;
}).pop();
return companyFactory.createCompany(company, visitor);
});
}
function getList(visitor) {
return fetchData().then(function(resp) {
return companyFactory.createCollection(resp.data, visitor);
});
}
return {
getList: getList,
getById: getById
};
});
<table class="table table-bordered">
<thead>
<tr>
<th>Company Name</th>
<th>Web Address</th>
<th>Lat/Long</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="company in companies">
<td>
<a ng-show="listPlus" ng-href="#/company/{{company.duns}}">{{company.name}}</a>
<span ng-hide="listPlus">{{company.name}}</span>
</td>
<td>{{company.webAddress}}</td>
<td><span ng-show="company.address.latitude">{{company.address.latitude}} / {{company.address.longitude}}</span></td>
</tr>
</tbody>
</table>
<table class="table table-bordered">
<thead>
<tr>
<th>Company Name</th>
<th>Web Address</th>
<th>Lat/Long</th>
<th>CRM Status</th>
<th>Add to CRM</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="company in companies">
<td>
<a ng-show="listPlus" ng-href="#/company/{{company.duns}}">{{company.name}}</a>
<span ng-hide="listPlus">{{company.name}}</span>
</td>
<td>{{company.webAddress}}</td>
<td><span ng-show="company.address.latitude">{{company.address.latitude}} / {{company.address.longitude}}</span></td>
<td><span ng-show="company.inCRM">Added</span></td>
<td>
<button ng-hide="company.inCRM" class="button" ng-click="company.addToCRM()">+</button>
<button ng-show="company.inCRM" class="button" ng-click="company.removeFromCRM()">-</button>
</td>
</tr>
</tbody>
</table>
<div class="jumbotron">
<h1>{{company.name}}</h1>
<p class="lead">Cras justo odio, dapibus ac facilisis in, egestas eget quam. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.</p>
<button class="btn btn-lg btn-danger pull-left" ng-click="company.subtract()" role="button">↓</button>
<button class="btn btn-lg btn-success" ng-click="company.add()" role="button">↑</button>
<h1 class="pull-right">{{company.count}}</h1>
</div>
<div class="well" ng-if="company.plus">
<h3>Editorial</h3>
<p>{{company.text || '...'}}</p>
<button class="btn btn-warning pull-right clearfix" ng-click="company.getText(company)" ng-if="!company.text">Get Additional info!</button>
<hr />
<h3>Your Notes</h3>
<p>{{company.notes || 'N/A'}}</p>
</div>
<div class="well" ng-if="company.plus">
<h4>Record Notes:</h4>
<textarea class="form-control" ng-model="company.notes"></textarea>
</div>
<button class="btn btn-default" ng-click="company.log()">Log to console</button>
<button ng-if="company.plus" class="btn btn-default" ng-click="company.saveCompany(company)">Save</button>
<span ng-show="company.saved">Saved!</span>
// model provider
angular.module('baseModel').factory('companyFactory', function(Company, BaseCompany, CompanyCRMVisitor) {
Company.prototype = new BaseCompany();
var globalVisitor;
var companyFactory = {
setGlobalVisitor: function(visitor) {
globalVisitor = visitor;
},
createCompany: function(obj, visitor) {
var company = new Company(obj);
if (globalVisitor) {
angular.extend(company, globalVisitor);
}
if (visitor) {
angular.extend(company, visitor);
}
return company;
},
createCollection: function(data, visitor) {
var companies = [];
data.forEach(function(obj) {
this.push(companyFactory.createCompany(obj, visitor));
}, companies)
return companies;
},
};
return companyFactory;
});