Reputation: 8638
I'm new to the AngularJS world and come from a Backbone background. So far I'm loving it but there is quite a big difference in terms of architecture practices between the two ( someone should write an article on this lol ).
I'm starting to structure some quite large controllers and it just doesn't feel right. For instance, this is a basic control that deals with executing a search and populating the ng-grid control and infinite scrolling this grid.
var ctrl = ['$scope', 'model', '$modal', function ($scope, model, $modal) {
$scope.page = 0;
$scope.loading = true;
$scope.mySelections = [];
$scope.rows = [];
$scope.columnDefs = [{
field: 'Checked',
width: "50",
sortable: false,
headerCellTemplate: '<input class="ngSelectionHeader" type="checkbox" ng-show="multiSelect" ng-model="allSelected" ng-change="toggleSelectAll(allSelected)"/>',
cellTemplate: '<div class="ngSelectionCell"><input tabindex="-1" class="ngSelectionCheckbox" type="checkbox" ng-checked="row.selected" /></div>'
}];
$scope.gridOptions = {
data: 'rows',
columnDefs: "columnDefs",
enableColumnResize: true,
selectedItems: $scope.mySelections,
};
/**
* Pages the grid and returns a $.deferred
*/
var pageGrid = function () {
return model.ExecuteSearchForReport("4146", ++$scope.page)
.done(function (records) {
$.each(records, function (i, record) {
var fields = {};
$.each(record.Value, function (ii, field) {
var fieldKey = field.Key.replace(/\s/g, '');
fields[fieldKey] = field.Value;
});
$scope.rows.push(fields)
});
$scope.$digest();
});
};
/**
* Page the grid initally.
*/
pageGrid().done(function (records) {
createColumns(records);
$scope.loading = false;
// if the grid height
var gridHeight = $('.ngGrid').height();
var repage = function () {
if ($('.ngCanvas').height() < gridHeight) {
pageGrid().done(function () {
repage();
});
}
};
repage();
$scope.$digest();
});
/**
* Creates the columns for the grid based on the records.
*/
var createColumns = function (records) {
if (records.length) {
$.each(records[0].Value, function (ii, field) {
var fieldKey = field.Key.replace(/\s/g, '');
var col = {
field: fieldKey,
displayName: field.Key,
resizable: true
};
// all the other columns are small
if (fieldKey !== "FileName") {
col.width = "100";
}
$scope.columnDefs.push(col);
});
}
};
/**
* List for `ngGridEventScroll` event to page the data set.
*/
$scope.$on('ngGridEventScroll', function () {
pageGrid();
});
/**
* Move the secure button was clicked, load next screen.
*/
$scope.moveToSecure = function () {
$scope.loading = true;
model.GetSecureDetails().done(function (data) {
$scope.loading = false;
var modalInstance = $modal.open({
templateUrl: 'Views/Modal.html',
controller: ModalInstanceCtrl,
resolve: {
data: function(){
return {
header: "Move To Secure",
body: "Views/Move.html",
lists: data
};
}
}
});
modalInstance.result.then(function (formData) {
var defs = [];
$.each($scope.mySelections, function (i, sel) {
defs.push(model.MoveToSecure({
Id: sel.EventID.substring(4, sel.EventID.length),
Filename: sel.FileName
}));
});
$.when.apply($, defs).done(function () {
alert('Move completed');
});
});
});
};
}];
I know, its a lot and it feels unstructured somewhat to me, between all the variable initialization, private methods, and general initialization methods. It doesn't feel concise and deterministic to me, which is something I liked about Backbone. Anyone got any feedback on a better way to do this? Thanks!
Upvotes: 0
Views: 500
Reputation: 7588
You need to move most of that stuff into 'concise' directives. If you don't master directives, your controllers will always end up overburdened and crazy like this. Ideally your controller pretty much only takes data back and forth between your scope and services.
Upvotes: 3