AngularJS Bound Sorter

Widget that allows ordering of items on the front end to automatically update back end.

by sc0ttyd

HTML

<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/css/bootstrap-combined.min.css">
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/js/bootstrap.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.js"></script>
<script src="http://code.angularjs.org/1.0.4/angular-resource.js"></script>
<script src="https://rawgit.com/pkozlowski-opensource/angularjs-mongolab/master/mongolab.js"></script>
<div ng-controller="Ctrl">
	    <h1>AngularJS Bound Sorter {{fail}}</h1>
    
        <ul ng-model="items" listbind></ul>

	    <button class="btn btn-primary" ng-click="addItem()">Add Item <i class="icon-plus-sign icon-white"></i></button>
    	<button class="btn btn-danger" ng-click="clearItems()">Clear Items <i class="icon-trash icon-white"></i></button>
    	<button class="btn btn-info" ng-click="dbgr()">Debug  <i class="icon-wrench icon-white"></i></button>
    	<button class="btn btn-info" ng-click="spit()">Spit</button>
	</div>

JavaScript

'use strict';
/**
 * AngularJS Bound Sorter
 * Scott Donnelly
 */

var app = angular.module('app', ['mongolabResource', 'directives', 'controllers']);

/***** MongoLab Resource Setup *****/
// Creds: https://github.com/pkozlowski-opensource - Thanks Pawel!
app.constant('API_KEY', '33g_6AM45HadHlJ_nTSS7KwKSC_lZYcg');
app.constant('DB_NAME', 'jsfiddle');
app.factory('Item', function($mongolabResource) { return $mongolabResource('items'); });

/***** Directive *****/
angular.module('directives', []).directive('listbind', function () {
    return {
        restrict: 'A',
        require: '?ngModel',
        link: function (scope, element, attrs, ngModel) {
            if(!ngModel) return; // do nothing if no ng-model
 
            // give the element an ID if it has none
            if (!element.id) element.id = 'ols' + new Date().getTime();
            
            // Specify how UI should be updated
            ngModel.$render = function() {
                console.log(this);
                var out = '';
                if (ngModel.$modelValue) {
                    for (var i = 0; i < ngModel.$modelValue.length; i++) {
                        out += '<li class="btn" id="' + element.id + '_' + i + '">' + ngModel.$viewValue[i].name + ' (' + ngModel.$modelValue[i].sort_order + ')</li>';
                    }
                }
                element.html(out);
            };
 
            // Listen for change events to enable binding
            element.bind('sortstop', function(event, ui) {
              scope.$apply(read);
            });
 
            // read from the view and write to the model
            function read() {
              // get array of DOM id's of children, in order 
              var domIdList = $(element).sortable("toArray");
                
              var oldModel = ngModel.$modelValue;
              var insertLocation = -1;
              var inserteeIndex = -1;
              for (var i = 0; i < domIdList.length; i++) {
                 ...