Skip to content

Instantly share code, notes, and snippets.

@srph
Last active January 16, 2024 14:13
Show Gist options
  • Save srph/2e3a7c57328d663afed4 to your computer and use it in GitHub Desktop.
Save srph/2e3a7c57328d663afed4 to your computer and use it in GitHub Desktop.
Example for Writing Better AngularJS Apps https://medium.com/p/f2ab70a104d0/
angular
.module('app')
.directive('productCategoryRow', productCategoryRow);
function productCategoryRow() {
return {
restrict: 'EA',
scope: { title: '@productCategoryRow' },
template: templateFn,
controller: controllerFn,
controllerAs: 'categoryCtrl',
// So our isolated scope will be stored
// on the ```this``` context of our controller
// instead of $scope
bindToController: true
}
function templateFn() {
return [
// Title
// Minimize
// Whatever
].join('');
}
function controllerFn($scope) {
var vm = this;
// Whatever..
}
}
angular
.module('app')
.directive('productRow', productRow);
function productRow() {
return {
restrict: 'EA',
scope: { data: '=productRow' },
template: templateFn,
controller: controllerFn,
controllerAs: 'rowCtrl',
// So our isolated scope will be stored
// on the ```this``` context of our controller
// instead of $scope
bindToController: true
}
function templateFn() {
return [
// Product name
// Whatever?
].join('');
}
function controllerFn($scope) {
var vm = this;
// Whatever..
}
}
angular
.module('app')
.directive('productTable', productTable);
function productTable() {
return {
restrict: 'EA',
scope: { filter: '@', data: '=productTable' },
template: templateFn,
controller: controllerFn,
controllerAs: 'tableCtrl',
// So our isolated scope will be stored
// on the ```this``` context of our controller
// instead of $scope
bindToController: true
}
function templateFn() {
return [
'<section>',
'<div ng-repeat="category in filtered() | filter: tableCtrl.filter " ng-if="!!category.products.length"> ',
'<div product-row-header="{{ category.name }}"></div>',
'<div ng-repeat="product in category.products" product-row="product"></div>',
'</div>',
'</div>'
].join('');
}
function controllerFn($scope) {
var vm = this;
var _categories = [];
angular.extend(vm, { filtered: filtered });
// I decided to use our own filter since
// our data is kind of different
function filtered() {
// For first time use, let's get our headers.
if ( !_categories.length ) {
getCategories();
}
return _categories.map(function(category) {
return vm.data.filter(function(product) { return category == product.category });
});
}
function getCategories() {
return vm.data.map(function(product) {
if ( _categories.indexOf(product.category) !== -1 )
return;
_headers.push(property.category);
return product.category;
});
}
}
}
// Our html would be,
// <product-search="productCtrl.filter"></product-table>
// <product-table="productCtrl.data"></product-table>
// Controller As productCtrl
angular
.module('app')
.controller('ProductController', ProductController);
function ProductController($scope, $http) {
// If you are unfamiliar with this code style,
// please check John Papa's or Todd Moto's Style Guide
var vm = this;
angular.extend(vm, { filter: '' });
// Since this is an example,
// I'd directly write an $http here.
// Supposedly, you should ajax-calls wrap in a service
$http.get('products.json')
.then(function(response) { vm.data })
.catch(function() { alert('An error has occured') });
}
[
{category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"},
{category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"},
{category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"},
{category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"},
{category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"},
{category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"}
];
angular
.module('app')
.directive('productSearchBar', productSearchBar);
function productSearchBar() {
return {
restrict: 'EA',
scope: { filter: '=' },
template: templateFn,
controller: controllerFn,
controllerAs: 'searchCtrl',
// So our isolated scope will be stored
// on the ```this``` context of our controller
// instead of $scope
bindToController: true
}
function templateFn() {
return [
// Input
].join('');
}
function controllerFn($scope) {
var vm = this;
// Whatever..
}
}
@tinyfly
Copy link

tinyfly commented Dec 23, 2014

Shouldn't your directives use .directive instead of .controller?

angular
  .module('app')
  .controller('productCategoryRow', productCategoryRow);

@royling
Copy link

royling commented Dec 24, 2014

@tinyfly +1, I come here for pointing that too 😄

@riddla
Copy link

riddla commented Jan 5, 2015

++ :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment