From 2cfd582db2a5f93eb7a48013e00f2235d406e545 Mon Sep 17 00:00:00 2001 From: Dylan Robinson Date: Tue, 9 Dec 2014 10:33:33 -0500 Subject: [PATCH] Improve Angular digest performance by allowing watching table definitions shallowly --- dist/angular-datatables.js | 14 ++++++++++++-- dist/angular-datatables.min.js | 2 +- src/angular-datatables.directive.js | 17 ++++++++++++----- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/dist/angular-datatables.js b/dist/angular-datatables.js index c58fefacf..a765d10db 100644 --- a/dist/angular-datatables.js +++ b/dist/angular-datatables.js @@ -375,7 +375,7 @@ compile: function (tElm) { var _staticHTML = tElm[0].innerHTML; return function postLink($scope, $elem, iAttrs, ctrl) { - $scope.$watch('[dtOptions, dtColumns, dtColumnDefs]', function (newVal, oldVal) { + function handleChanges(newVal, oldVal) { if (newVal !== oldVal) { var newDTOptions = newVal[0], oldDTOptions = oldVal[0]; // Do not rerender if we want to reload. There are already @@ -388,7 +388,17 @@ newDTOptions.reload = false; } } - }, true); + } + // Options can hold heavy data, and other deep/large objects. + // watchcollection can improve this by only watching shallowly + var watchFunction = iAttrs.disableDeepWatchers ? '$watchCollection' : '$watch'; + angular.forEach([ + 'dtColumns', + 'dtColumnDefs', + 'dtOptions' + ], function (tableDefField) { + $scope[watchFunction].call($scope, tableDefField, handleChanges, true); + }); ctrl.showLoading($elem); ctrl.render($elem, ctrl.buildOptionsPromise(), _staticHTML); }; diff --git a/dist/angular-datatables.min.js b/dist/angular-datatables.min.js index ac6f37bf9..36746553a 100644 --- a/dist/angular-datatables.min.js +++ b/dist/angular-datatables.min.js @@ -3,4 +3,4 @@ * https://github.com/l-lin/angular-datatables * License: MIT */ -!function(a,b,c,d){"use strict";d.module("datatables.bootstrap.tabletools",["datatables.bootstrap.options","datatables.util"]).service("DTBootstrapTableTools",["DTPropertyUtil","DTBootstrapDefaultOptions",function(a,b){var e=!1,f={},g=function(){c.fn.DataTable.TableTools&&(f.TableTools={classes:d.copy(c.fn.DataTable.TableTools.classes),oTags:d.copy(c.fn.DataTable.TableTools.DEFAULTS.oTags)})};this.integrate=function(d){if(!e){if(g(),c.fn.DataTable.TableTools){var f=a.overrideProperties(b.getOptions().TableTools,d?d.TableTools:null);c.extend(!0,c.fn.DataTable.TableTools.classes,f.classes),c.extend(!0,c.fn.DataTable.TableTools.DEFAULTS.oTags,f.DEFAULTS.oTags)}e=!0}},this.deIntegrate=function(){e&&c.fn.DataTable.TableTools&&f.TableTools&&(c.extend(!0,c.fn.DataTable.TableTools.classes,f.TableTools.classes),c.extend(!0,c.fn.DataTable.TableTools.DEFAULTS.oTags,f.TableTools.oTags),e=!1)}}]),d.module("datatables.bootstrap.colvis",["datatables.bootstrap.options","datatables.util"]).service("DTBootstrapColVis",["DTPropertyUtil","DTBootstrapDefaultOptions",function(a,b){var d=!1;this.integrate=function(e,f){if(!d){var g=a.overrideProperties(b.getOptions().ColVis,f?f.ColVis:null);c.fn.DataTable.ColVis&&e(function(){c(".ColVis_MasterButton").attr("class","ColVis_MasterButton "+g.classes.masterButton),c(".ColVis_Button").removeClass("ColVis_Button")}),d=!0}},this.deIntegrate=function(){d&&c.fn.DataTable.ColVis&&(d=!1)}}]),d.module("datatables.bootstrap",["datatables.bootstrap.options","datatables.bootstrap.tabletools","datatables.bootstrap.colvis"]).service("DTBootstrap",["DTBootstrapTableTools","DTBootstrapColVis","DTBootstrapDefaultOptions",function(a,e,f){var g=!1,h=[],i={},j=function(){i.oStdClasses=d.copy(c.fn.dataTableExt.oStdClasses),i.fnPagingInfo=c.fn.dataTableExt.oApi.fnPagingInfo,i.renderer=d.copy(c.fn.DataTable.ext.renderer),c.fn.DataTable.TableTools&&(i.TableTools={classes:d.copy(c.fn.DataTable.TableTools.classes),oTags:d.copy(c.fn.DataTable.TableTools.DEFAULTS.oTags)})},k=function(){c.extend(c.fn.dataTableExt.oStdClasses,i.oStdClasses),c.fn.dataTableExt.oApi.fnPagingInfo=i.fnPagingInfo,c.extend(!0,c.fn.DataTable.ext.renderer,i.renderer)},l=function(){c.extend(c.fn.dataTableExt.oStdClasses,{sWrapper:"dataTables_wrapper form-inline",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm",sFilter:"dataTables_filter",sLength:"dataTables_length"})},m=function(){c.fn.dataTableExt.oApi.fnPagingInfo=function(a){return{iStart:a._iDisplayStart,iEnd:a.fnDisplayEnd(),iLength:a._iDisplayLength,iTotal:a.fnRecordsTotal(),iFilteredTotal:a.fnRecordsDisplay(),iPage:-1===a._iDisplayLength?0:Math.ceil(a._iDisplayStart/a._iDisplayLength),iTotalPages:-1===a._iDisplayLength?0:Math.ceil(a.fnRecordsDisplay()/a._iDisplayLength)}}},n=function(){c.extend(!0,c.fn.DataTable.ext.renderer,{pageButton:{_:function(a,d,e,f,g,h){var i,j,k=a.oClasses,l=a.oLanguage.oPaginate,m=0,n=c("",{"class":"pagination"}),o=function(b,d){var f,p,q,r,s=function(b){b.preventDefault(),c.fn.DataTable.ext.internal._fnPageChange(a,b.data.action,!0)};for(f=0,p=d.length;p>f;f++)if(r=d[f],c.isArray(r)){r.DT_el="li";var t=c("<"+(r.DT_el||"div")+"/>").appendTo(n);o(t,r)}else{i="",j="";var u,v=c("
  • ");switch(r){case"ellipsis":n.append('
  • ');break;case"first":i=l.sFirst,j=r,0>=g&&(v.addClass(k.sPageButtonDisabled),u=!0);break;case"previous":i=l.sPrevious,j=r,0>=g&&(v.addClass(k.sPageButtonDisabled),u=!0);break;case"next":i=l.sNext,j=r,g>=h-1&&(v.addClass(k.sPageButtonDisabled),u=!0);break;case"last":i=l.sLast,j=r,g>=h-1&&(v.addClass(k.sPageButtonDisabled),u=!0);break;default:i=r+1,j="",g===r&&v.addClass(k.sPageButtonActive)}i&&(v.appendTo(n),q=c("",{href:"#","class":j,"aria-controls":a.sTableId,"data-dt-idx":m,tabindex:a.iTabIndex,id:0===e&&"string"==typeof r?a.sTableId+"_"+r:null}).html(i).appendTo(v),c.fn.DataTable.ext.internal._fnBindAction(q,{action:r},s),m++)}};try{var p=c(b.activeElement).data("dt-idx"),q=c(d).empty();n.appendTo(q),o(q,f),null!==p&&c(d).find("[data-dt-idx="+p+"]").focus()}catch(r){}}}})},o=function(a){d.isFunction(a)&&h.push(a)},p=function(){g||(j(),l(),m(),n(),o(function(){c("div.dataTables_filter").find("input").addClass("form-control"),c("div.dataTables_length").find("select").addClass("form-control")}),g=!0)},q=function(a){if(!a.hasOverrideDom){var b=f.getOptions().dom;return a.hasColReorder&&(b="R"+b),a.hasColVis&&(b="C"+b),a.hasTableTools&&(b="T"+b),b}return a.sDom};this.integrate=function(b){p(),a.integrate(b.bootstrap),e.integrate(o,b.bootstrap),b.sDom=q(b),d.isUndefined(b.fnDrawCallback)&&(b.fnDrawCallback=function(){for(var a=0;a<'col-xs-6'f>r>t<'row'<'col-xs-6'i><'col-xs-6'p>>"}).service("DTBootstrapDefaultOptions",["DTDefaultOptions","DTPropertyUtil","DT_BOOTSTRAP_DEFAULT_OPTIONS",function(a,b,c){this.getOptions=function(){return b.overrideProperties(c,a.bootstrapOptions)}}]),d.module("datatables.directive",["datatables.renderer","datatables.options","datatables.util"]).directive("datatable",["$q","DT_DEFAULT_OPTIONS","DTBootstrap","DTRendererFactory","DTRendererService","DTPropertyUtil",function(a,b,c,e,f,g){return{restrict:"A",scope:{dtOptions:"=",dtColumns:"=",dtColumnDefs:"=",datatable:"@"},compile:function(a){var b=a[0].innerHTML;return function(a,c,d,e){a.$watch("[dtOptions, dtColumns, dtColumnDefs]",function(a,d){if(a!==d){var f=a[0],g=d[0];f.reload&&f.sAjaxSource===g.sAjaxSource?f.reload=!1:e.render(c,e.buildOptionsPromise(),b)}},!0),e.showLoading(c),e.render(c,e.buildOptionsPromise(),b)}},controller:["$scope",function(b){var h;this.showLoading=function(a){f.showLoading(a)},this.buildOptionsPromise=function(){var e=a.defer();return a.all([a.when(b.dtOptions),a.when(b.dtColumns),a.when(b.dtColumnDefs)]).then(function(a){var f=a[0],h=a[1],i=a[2];g.deleteProperty(f,"$promise"),g.deleteProperty(h,"$promise"),g.deleteProperty(i,"$promise");var j;d.isDefined(b.dtOptions)&&(j={},d.extend(j,f),d.isArray(h)&&(j.aoColumns=h),d.isArray(i)&&(j.aoColumnDefs=i),j.integrateBootstrap?c.integrate(j):c.deIntegrate()),e.resolve(j)}),e.promise},this.render=function(a,c,d){c.then(function(c){var f=b.datatable&&"ng"===b.datatable;h?h.withOptions(c).render(b,a,d):h=e.fromOptions(c,f).render(b,a,d)})}}]}}]),d.module("datatables.factory",["datatables.bootstrap","datatables.options"]).factory("DTOptionsBuilder",["DT_DEFAULT_OPTIONS",function(a){var b={isPresent:function(){return d.isDefined(this.obj)&&null!==this.obj},orEmptyObj:function(){return this.isPresent()?this.obj:{}},or:function(a){return this.isPresent()?this.obj:a}},c=function(a){var c=Object.create(b);return c.obj=a,c},e={integrateBootstrap:!1,hasColVis:!1,hasColReorder:!1,hasTableTools:!1,hasOverrideDom:!1,reloadData:function(){return this.reload=!0,this},withOption:function(a,b){return d.isString(a)&&(this[a]=b),this},withSource:function(a){return this.sAjaxSource=a,this},withDataProp:function(a){return this.sAjaxDataProp=a,this},withFnServerData:function(a){if(!d.isFunction(a))throw new Error("The parameter must be a function");return this.fnServerData=a,this},withPaginationType:function(a){if(!d.isString(a))throw new Error("The pagination type must be provided");return this.sPaginationType=a,this},withLanguage:function(a){return this.oLanguage=a,this},withLanguageSource:function(a){return this.withLanguage({sUrl:a})},withDisplayLength:function(a){return this.iDisplayLength=a,this},withFnPromise:function(a){return this.fnPromise=a,this},withDOM:function(a){return this.sDom=a,this.hasOverrideDom=!0,this},withBootstrap:function(){return this.integrateBootstrap=!0,d.isObject(this.oClasses)?this.oClasses.sPageButtonActive="active":this.oClasses={sPageButtonActive:"active"},this},withBootstrapOptions:function(a){return this.bootstrap=a,this},withColReorderOption:function(a,b){return d.isString(a)&&(this.oColReorder=c(this.oColReorder).orEmptyObj(),this.oColReorder[a]=b),this},withColReorder:function(){var b="R";return this.sDom=b+c(this.sDom).or(a.dom),this.hasColReorder=!0,this},withColReorderOrder:function(a){return d.isArray(a)&&this.withColReorderOption("aiOrder",a),this},withColReorderCallback:function(a){if(!d.isFunction(a))throw new Error("The reorder callback must be a function");return this.withColReorderOption("fnReorderCallback",a),this},withColVisOption:function(a,b){return d.isString(a)&&(this.oColVis=c(this.oColVis).orEmptyObj(),this.oColVis[a]=b),this},withColVis:function(){var b="C";return this.sDom=b+c(this.sDom).or(a.dom),this.hasColVis=!0,this},withColVisStateChange:function(a){if(!d.isFunction(a))throw new Error("The state change must be a function");return this.withColVisOption("fnStateChange",a),this},withTableToolsOption:function(a,b){return d.isString(a)&&(this.oTableTools=c(this.oTableTools).orEmptyObj(),this.oTableTools[a]=b),this},withTableTools:function(b){var e="T";return this.sDom=e+c(this.sDom).or(a.dom),this.hasTableTools=!0,d.isString(b)&&this.withTableToolsOption("sSwfPath",b),this},withTableToolsButtons:function(a){return d.isArray(a)&&this.withTableToolsOption("aButtons",a),this},withScroller:function(){var b="S";return this.sDom=c(this.sDom).or(a.dom)+b,this}};return{newOptions:function(){return Object.create(e)},fromSource:function(a){var b=Object.create(e);return b.sAjaxSource=a,b},fromFnPromise:function(a){var b=Object.create(e);return b.fnPromise=a,b}}}]).factory("DTColumnBuilder",function(){var a={withOption:function(a,b){return d.isString(a)&&(this[a]=b),this},withTitle:function(a){return this.sTitle=a,this},withClass:function(a){return this.sClass=a,this},notVisible:function(){return this.bVisible=!1,this},notSortable:function(){return this.bSortable=!1,this},renderWith:function(a){return this.mRender=a,this}};return{newColumn:function(b,c){if(d.isUndefined(b))throw new Error('The parameter "mData" is not defined!');var e=Object.create(a);return e.mData=b,e.sTitle=c||"",e},DTColumn:a}}).factory("DTColumnDefBuilder",["DTColumnBuilder",function(a){return{newColumnDef:function(b){if(d.isUndefined(b))throw new Error('The parameter "targets" must be defined! See https://datatables.net/reference/option/columnDefs.targets');var c=Object.create(a.DTColumn);return c.aTargets=d.isArray(b)?b:[b],c}}}]).factory("DTLoadingTemplate",function(){return{html:'

    Loading...

    '}}),d.module("datatables",["datatables.directive","datatables.factory","datatables.bootstrap"]).run(["$log",function(b){c.fn.DataTable.Api&&c.fn.DataTable.Api.register("ngDestroy()",function(d){return d=d||!1,this.iterator("table",function(e){var f,g=e.nTableWrapper.parentNode,h=e.oClasses,i=e.nTable,j=e.nTBody,k=e.nTHead,l=e.nTFoot,m=c(i),n=c(j),o=c(e.nTableWrapper),p=c.map(e.aoData,function(a){return a.nTr});if(e.bDestroying=!0,c.fn.DataTable.ext.internal._fnCallbackFire(e,"aoDestroyCallback","destroy",[e]),d||new c.fn.DataTable.Api(e).columns().visible(!0),o.unbind(".DT").find(":not(tbody *)").unbind(".DT"),c(a).unbind(".DT-"+e.sInstance),i!==k.parentNode&&(m.children("thead").detach(),m.append(k)),l&&i!==l.parentNode&&(m.children("tfoot").detach(),m.append(l)),m.detach(),o.detach(),e.aaSorting=[],e.aaSortingFixed=[],c.fn.DataTable.ext.internal._fnSortingClasses(e),c(p).removeClass(e.asStripeClasses.join(" ")),c("th, td",k).removeClass(h.sSortable+" "+h.sSortableAsc+" "+h.sSortableDesc+" "+h.sSortableNone),e.bJUI&&(c("th span."+h.sSortIcon+", td span."+h.sSortIcon,k).detach(),c("th, td",k).each(function(){var a=c("div."+h.sSortJUIWrapper,this);c(this).append(a.contents()),a.detach()})),!d&&g)try{g.insertBefore(i,e.nTableReinsertBefore)}catch(q){b.warn(q),g.appendChild(i)}m.css("width",e.sDestroyWidth).removeClass(h.sTable),f=e.asDestroyStripes.length,f&&n.children().each(function(a){c(this).addClass(e.asDestroyStripes[a%f])});var r=c.inArray(e,c.fn.DataTable.settings);-1!==r&&c.fn.DataTable.settings.splice(r,1)})})}]),d.module("datatables.options",[]).constant("DT_DEFAULT_OPTIONS",{dom:"lfrtip",sAjaxDataProp:"",aoColumns:[]}).service("DTDefaultOptions",function(){this.bootstrapOptions={},this.setLanguageSource=function(a){return c.extend(c.fn.dataTable.defaults,{oLanguage:{sUrl:a}}),this},this.setLanguage=function(a){return c.extend(!0,c.fn.dataTable.defaults,{oLanguage:a}),this},this.setDisplayLength=function(a){return c.extend(c.fn.dataTable.defaults,{iDisplayLength:a}),this},this.setBootstrapOptions=function(a){return this.bootstrapOptions=a,this}}),d.module("datatables.renderer",["datatables.factory","datatables.options"]).factory("DTRendererService",["DTLoadingTemplate",function(a){var b=d.element(a.html);return{getLoadingElem:function(){return b},showLoading:function(a){a.after(b),a.hide(),b.show()},hideLoading:function(a){a.show(),b.hide()},renderDataTableAndEmitEvent:function(a,b,d){var e="#"+a.attr("id");c.fn.dataTable.isDataTable(e)&&(b.destroy=!0);var f=a.DataTable(b);return d.$emit("event:dataTableLoaded",{id:a.attr("id"),DataTable:f,dataTable:a.dataTable()}),f},doRenderDataTable:function(a,b,c){return this.hideLoading(a),this.renderDataTableAndEmitEvent(a,b,c)}}}]).factory("DTRenderer",function(){return{withOptions:function(a){return this.options=a,this}}}).factory("DTDefaultRenderer",["$timeout","DTRenderer","DTRendererService",function(a,b,c){return{create:function(d){var e=Object.create(b);return e.name="DTDefaultRenderer",e.options=d,e.render=function(b,d){var e=this;return a(function(){c.doRenderDataTable(d,e.options,b)},0,!1),e},e}}}]).factory("DTNGRenderer",["$compile","$timeout","DTRenderer","DTRendererService",function(a,b,c,d){return{create:function(e){var f=Object.create(c);return f.name="DTNGRenderer",f.options=e,f.render=function(c,e,f){var g=this,h=e.find("tbody").html(),i=h.match(/^\s*.+?\s+in\s+(\S*)\s*/),j=i[1];if(!i)throw new Error('Expected expression in form of "_item_ in _collection_[ track by _id_]" but got "{0}".',h);var k,l=!1,m=c.$parent;return m.$watchCollection(j,function(){k&&l&&(k.ngDestroy(),e.html(f),a(e.contents())(m)),b(function(){l=!0,k=d.doRenderDataTable(e,g.options,c)},0,!1)},!0),g},f}}}]).factory("DTPromiseRenderer",["$timeout","DTRenderer","DTRendererService",function(a,b,c){return{create:function(e){var f,g=!1,h=function(b,d,e,g){delete e.$promise,b.aaData=e,a(function(){c.hideLoading(d),b.bDestroy=!0,f?(f.clear(),f.rows.add(b.aaData).draw()):f=c.renderDataTableAndEmitEvent(d,b,g)},0,!1)},i=Object.create(b);return i.name="DTPromiseRenderer",i.options=e,i.render=function(a,b){var c=this,e=null,f=function(d){var f=d;c.options.sAjaxDataProp&&(f=d[c.options.sAjaxDataProp]),h(c.options,b,f,a),e=null},i=function(a){e=d.isFunction(a)?a():a,e.then(f)},j=function(a){if(!d.isDefined(a))throw new Error("You must provide a promise or a function that returns a promise!");e?e.then(function(){i(a)}):i(a)};return g||(a.$watch("dtOptions.fnPromise",function(a,b){a!==b&&j(a)}),g=!0),j(a.dtOptions.fnPromise),c},i}}}]).factory("DTAjaxRenderer",["$timeout","DTRenderer","DTRendererService","DT_DEFAULT_OPTIONS",function(a,b,c,e){return{create:function(f){var g,h=function(a,b,c,e){d.isDefined(b)&&(a.sAjaxSource=b,d.isDefined(a.ajax)&&(d.isObject(a.ajax)?a.ajax.url=b:a.ajax={url:b})),i(a,c,e)},i=function(b,d,e){b.bDestroy=!0,a(function(){if(c.hideLoading(d),g){var a=b.sAjaxSource||b.ajax.url||b.ajax;g.ajax.url(a).load()}else g=c.renderDataTableAndEmitEvent(d,b,e)},0,!1)},j=Object.create(b);return j.name="DTAjaxRenderer",j.options=f,j.render=function(a,b){var c=this;return d.isUndefined(c.options.sAjaxDataProp)&&(c.options.sAjaxDataProp=e.sAjaxDataProp),d.isUndefined(c.options.aoColumns)&&(c.options.aoColumns=e.aoColumns),h(c.options,c.options.sAjaxSource,b,a),this},j}}}]).factory("DTRendererFactory",["DTDefaultRenderer","DTNGRenderer","DTPromiseRenderer","DTAjaxRenderer",function(a,b,c,e){return{fromOptions:function(f,g){return g?b.create(f):d.isDefined(f)?d.isDefined(f.fnPromise)&&null!==f.fnPromise?c.create(f):d.isDefined(f.sAjaxSource)&&null!==f.sAjaxSource||d.isDefined(f.ajax)&&null!==f.ajax?e.create(f):a.create(f):a.create()}}}]),d.module("datatables.util",[]).factory("DTPropertyUtil",function(){return{overrideProperties:function(a,b){var c=d.copy(a);if((d.isUndefined(c)||null===c)&&(c={}),d.isUndefined(b)||null===b)return c;if(d.isObject(b))for(var e in b)b.hasOwnProperty(e)&&(c[e]=this.overrideProperties(c[e],b[e]));else c=d.copy(b);return c},deleteProperty:function(a,b){d.isObject(a)&&delete a[b]}}})}(window,document,jQuery,angular); \ No newline at end of file +!function(a,b,c,d){"use strict";d.module("datatables.bootstrap.tabletools",["datatables.bootstrap.options","datatables.util"]).service("DTBootstrapTableTools",["DTPropertyUtil","DTBootstrapDefaultOptions",function(a,b){var e=!1,f={},g=function(){c.fn.DataTable.TableTools&&(f.TableTools={classes:d.copy(c.fn.DataTable.TableTools.classes),oTags:d.copy(c.fn.DataTable.TableTools.DEFAULTS.oTags)})};this.integrate=function(d){if(!e){if(g(),c.fn.DataTable.TableTools){var f=a.overrideProperties(b.getOptions().TableTools,d?d.TableTools:null);c.extend(!0,c.fn.DataTable.TableTools.classes,f.classes),c.extend(!0,c.fn.DataTable.TableTools.DEFAULTS.oTags,f.DEFAULTS.oTags)}e=!0}},this.deIntegrate=function(){e&&c.fn.DataTable.TableTools&&f.TableTools&&(c.extend(!0,c.fn.DataTable.TableTools.classes,f.TableTools.classes),c.extend(!0,c.fn.DataTable.TableTools.DEFAULTS.oTags,f.TableTools.oTags),e=!1)}}]),d.module("datatables.bootstrap.colvis",["datatables.bootstrap.options","datatables.util"]).service("DTBootstrapColVis",["DTPropertyUtil","DTBootstrapDefaultOptions",function(a,b){var d=!1;this.integrate=function(e,f){if(!d){var g=a.overrideProperties(b.getOptions().ColVis,f?f.ColVis:null);c.fn.DataTable.ColVis&&e(function(){c(".ColVis_MasterButton").attr("class","ColVis_MasterButton "+g.classes.masterButton),c(".ColVis_Button").removeClass("ColVis_Button")}),d=!0}},this.deIntegrate=function(){d&&c.fn.DataTable.ColVis&&(d=!1)}}]),d.module("datatables.bootstrap",["datatables.bootstrap.options","datatables.bootstrap.tabletools","datatables.bootstrap.colvis"]).service("DTBootstrap",["DTBootstrapTableTools","DTBootstrapColVis","DTBootstrapDefaultOptions",function(a,e,f){var g=!1,h=[],i={},j=function(){i.oStdClasses=d.copy(c.fn.dataTableExt.oStdClasses),i.fnPagingInfo=c.fn.dataTableExt.oApi.fnPagingInfo,i.renderer=d.copy(c.fn.DataTable.ext.renderer),c.fn.DataTable.TableTools&&(i.TableTools={classes:d.copy(c.fn.DataTable.TableTools.classes),oTags:d.copy(c.fn.DataTable.TableTools.DEFAULTS.oTags)})},k=function(){c.extend(c.fn.dataTableExt.oStdClasses,i.oStdClasses),c.fn.dataTableExt.oApi.fnPagingInfo=i.fnPagingInfo,c.extend(!0,c.fn.DataTable.ext.renderer,i.renderer)},l=function(){c.extend(c.fn.dataTableExt.oStdClasses,{sWrapper:"dataTables_wrapper form-inline",sFilterInput:"form-control input-sm",sLengthSelect:"form-control input-sm",sFilter:"dataTables_filter",sLength:"dataTables_length"})},m=function(){c.fn.dataTableExt.oApi.fnPagingInfo=function(a){return{iStart:a._iDisplayStart,iEnd:a.fnDisplayEnd(),iLength:a._iDisplayLength,iTotal:a.fnRecordsTotal(),iFilteredTotal:a.fnRecordsDisplay(),iPage:-1===a._iDisplayLength?0:Math.ceil(a._iDisplayStart/a._iDisplayLength),iTotalPages:-1===a._iDisplayLength?0:Math.ceil(a.fnRecordsDisplay()/a._iDisplayLength)}}},n=function(){c.extend(!0,c.fn.DataTable.ext.renderer,{pageButton:{_:function(a,d,e,f,g,h){var i,j,k=a.oClasses,l=a.oLanguage.oPaginate,m=0,n=c("
      ",{"class":"pagination"}),o=function(b,d){var f,p,q,r,s=function(b){b.preventDefault(),c.fn.DataTable.ext.internal._fnPageChange(a,b.data.action,!0)};for(f=0,p=d.length;p>f;f++)if(r=d[f],c.isArray(r)){r.DT_el="li";var t=c("<"+(r.DT_el||"div")+"/>").appendTo(n);o(t,r)}else{i="",j="";var u,v=c("
    • ");switch(r){case"ellipsis":n.append('
    • ');break;case"first":i=l.sFirst,j=r,0>=g&&(v.addClass(k.sPageButtonDisabled),u=!0);break;case"previous":i=l.sPrevious,j=r,0>=g&&(v.addClass(k.sPageButtonDisabled),u=!0);break;case"next":i=l.sNext,j=r,g>=h-1&&(v.addClass(k.sPageButtonDisabled),u=!0);break;case"last":i=l.sLast,j=r,g>=h-1&&(v.addClass(k.sPageButtonDisabled),u=!0);break;default:i=r+1,j="",g===r&&v.addClass(k.sPageButtonActive)}i&&(v.appendTo(n),q=c("",{href:"#","class":j,"aria-controls":a.sTableId,"data-dt-idx":m,tabindex:a.iTabIndex,id:0===e&&"string"==typeof r?a.sTableId+"_"+r:null}).html(i).appendTo(v),c.fn.DataTable.ext.internal._fnBindAction(q,{action:r},s),m++)}};try{var p=c(b.activeElement).data("dt-idx"),q=c(d).empty();n.appendTo(q),o(q,f),null!==p&&c(d).find("[data-dt-idx="+p+"]").focus()}catch(r){}}}})},o=function(a){d.isFunction(a)&&h.push(a)},p=function(){g||(j(),l(),m(),n(),o(function(){c("div.dataTables_filter").find("input").addClass("form-control"),c("div.dataTables_length").find("select").addClass("form-control")}),g=!0)},q=function(a){if(!a.hasOverrideDom){var b=f.getOptions().dom;return a.hasColReorder&&(b="R"+b),a.hasColVis&&(b="C"+b),a.hasTableTools&&(b="T"+b),b}return a.sDom};this.integrate=function(b){p(),a.integrate(b.bootstrap),e.integrate(o,b.bootstrap),b.sDom=q(b),d.isUndefined(b.fnDrawCallback)&&(b.fnDrawCallback=function(){for(var a=0;a<'col-xs-6'f>r>t<'row'<'col-xs-6'i><'col-xs-6'p>>"}).service("DTBootstrapDefaultOptions",["DTDefaultOptions","DTPropertyUtil","DT_BOOTSTRAP_DEFAULT_OPTIONS",function(a,b,c){this.getOptions=function(){return b.overrideProperties(c,a.bootstrapOptions)}}]),d.module("datatables.directive",["datatables.renderer","datatables.options","datatables.util"]).directive("datatable",["$q","DT_DEFAULT_OPTIONS","DTBootstrap","DTRendererFactory","DTRendererService","DTPropertyUtil",function(a,b,c,e,f,g){return{restrict:"A",scope:{dtOptions:"=",dtColumns:"=",dtColumnDefs:"=",datatable:"@"},compile:function(a){var b=a[0].innerHTML;return function(a,c,e,f){function g(a,d){if(a!==d){var e=a[0],g=d[0];e.reload&&e.sAjaxSource===g.sAjaxSource?e.reload=!1:f.render(c,f.buildOptionsPromise(),b)}}var h=e.disableDeepWatchers?"$watchCollection":"$watch";d.forEach(["dtColumns","dtColumnDefs","dtOptions"],function(b){a[h].call(a,b,g,!0)}),f.showLoading(c),f.render(c,f.buildOptionsPromise(),b)}},controller:["$scope",function(b){var h;this.showLoading=function(a){f.showLoading(a)},this.buildOptionsPromise=function(){var e=a.defer();return a.all([a.when(b.dtOptions),a.when(b.dtColumns),a.when(b.dtColumnDefs)]).then(function(a){var f=a[0],h=a[1],i=a[2];g.deleteProperty(f,"$promise"),g.deleteProperty(h,"$promise"),g.deleteProperty(i,"$promise");var j;d.isDefined(b.dtOptions)&&(j={},d.extend(j,f),d.isArray(h)&&(j.aoColumns=h),d.isArray(i)&&(j.aoColumnDefs=i),j.integrateBootstrap?c.integrate(j):c.deIntegrate()),e.resolve(j)}),e.promise},this.render=function(a,c,d){c.then(function(c){var f=b.datatable&&"ng"===b.datatable;h?h.withOptions(c).render(b,a,d):h=e.fromOptions(c,f).render(b,a,d)})}}]}}]),d.module("datatables.factory",["datatables.bootstrap","datatables.options"]).factory("DTOptionsBuilder",["DT_DEFAULT_OPTIONS",function(a){var b={isPresent:function(){return d.isDefined(this.obj)&&null!==this.obj},orEmptyObj:function(){return this.isPresent()?this.obj:{}},or:function(a){return this.isPresent()?this.obj:a}},c=function(a){var c=Object.create(b);return c.obj=a,c},e={integrateBootstrap:!1,hasColVis:!1,hasColReorder:!1,hasTableTools:!1,hasOverrideDom:!1,reloadData:function(){return this.reload=!0,this},withOption:function(a,b){return d.isString(a)&&(this[a]=b),this},withSource:function(a){return this.sAjaxSource=a,this},withDataProp:function(a){return this.sAjaxDataProp=a,this},withFnServerData:function(a){if(!d.isFunction(a))throw new Error("The parameter must be a function");return this.fnServerData=a,this},withPaginationType:function(a){if(!d.isString(a))throw new Error("The pagination type must be provided");return this.sPaginationType=a,this},withLanguage:function(a){return this.oLanguage=a,this},withLanguageSource:function(a){return this.withLanguage({sUrl:a})},withDisplayLength:function(a){return this.iDisplayLength=a,this},withFnPromise:function(a){return this.fnPromise=a,this},withDOM:function(a){return this.sDom=a,this.hasOverrideDom=!0,this},withBootstrap:function(){return this.integrateBootstrap=!0,d.isObject(this.oClasses)?this.oClasses.sPageButtonActive="active":this.oClasses={sPageButtonActive:"active"},this},withBootstrapOptions:function(a){return this.bootstrap=a,this},withColReorderOption:function(a,b){return d.isString(a)&&(this.oColReorder=c(this.oColReorder).orEmptyObj(),this.oColReorder[a]=b),this},withColReorder:function(){var b="R";return this.sDom=b+c(this.sDom).or(a.dom),this.hasColReorder=!0,this},withColReorderOrder:function(a){return d.isArray(a)&&this.withColReorderOption("aiOrder",a),this},withColReorderCallback:function(a){if(!d.isFunction(a))throw new Error("The reorder callback must be a function");return this.withColReorderOption("fnReorderCallback",a),this},withColVisOption:function(a,b){return d.isString(a)&&(this.oColVis=c(this.oColVis).orEmptyObj(),this.oColVis[a]=b),this},withColVis:function(){var b="C";return this.sDom=b+c(this.sDom).or(a.dom),this.hasColVis=!0,this},withColVisStateChange:function(a){if(!d.isFunction(a))throw new Error("The state change must be a function");return this.withColVisOption("fnStateChange",a),this},withTableToolsOption:function(a,b){return d.isString(a)&&(this.oTableTools=c(this.oTableTools).orEmptyObj(),this.oTableTools[a]=b),this},withTableTools:function(b){var e="T";return this.sDom=e+c(this.sDom).or(a.dom),this.hasTableTools=!0,d.isString(b)&&this.withTableToolsOption("sSwfPath",b),this},withTableToolsButtons:function(a){return d.isArray(a)&&this.withTableToolsOption("aButtons",a),this},withScroller:function(){var b="S";return this.sDom=c(this.sDom).or(a.dom)+b,this}};return{newOptions:function(){return Object.create(e)},fromSource:function(a){var b=Object.create(e);return b.sAjaxSource=a,b},fromFnPromise:function(a){var b=Object.create(e);return b.fnPromise=a,b}}}]).factory("DTColumnBuilder",function(){var a={withOption:function(a,b){return d.isString(a)&&(this[a]=b),this},withTitle:function(a){return this.sTitle=a,this},withClass:function(a){return this.sClass=a,this},notVisible:function(){return this.bVisible=!1,this},notSortable:function(){return this.bSortable=!1,this},renderWith:function(a){return this.mRender=a,this}};return{newColumn:function(b,c){if(d.isUndefined(b))throw new Error('The parameter "mData" is not defined!');var e=Object.create(a);return e.mData=b,e.sTitle=c||"",e},DTColumn:a}}).factory("DTColumnDefBuilder",["DTColumnBuilder",function(a){return{newColumnDef:function(b){if(d.isUndefined(b))throw new Error('The parameter "targets" must be defined! See https://datatables.net/reference/option/columnDefs.targets');var c=Object.create(a.DTColumn);return c.aTargets=d.isArray(b)?b:[b],c}}}]).factory("DTLoadingTemplate",function(){return{html:'

      Loading...

      '}}),d.module("datatables",["datatables.directive","datatables.factory","datatables.bootstrap"]).run(["$log",function(b){c.fn.DataTable.Api&&c.fn.DataTable.Api.register("ngDestroy()",function(d){return d=d||!1,this.iterator("table",function(e){var f,g=e.nTableWrapper.parentNode,h=e.oClasses,i=e.nTable,j=e.nTBody,k=e.nTHead,l=e.nTFoot,m=c(i),n=c(j),o=c(e.nTableWrapper),p=c.map(e.aoData,function(a){return a.nTr});if(e.bDestroying=!0,c.fn.DataTable.ext.internal._fnCallbackFire(e,"aoDestroyCallback","destroy",[e]),d||new c.fn.DataTable.Api(e).columns().visible(!0),o.unbind(".DT").find(":not(tbody *)").unbind(".DT"),c(a).unbind(".DT-"+e.sInstance),i!==k.parentNode&&(m.children("thead").detach(),m.append(k)),l&&i!==l.parentNode&&(m.children("tfoot").detach(),m.append(l)),m.detach(),o.detach(),e.aaSorting=[],e.aaSortingFixed=[],c.fn.DataTable.ext.internal._fnSortingClasses(e),c(p).removeClass(e.asStripeClasses.join(" ")),c("th, td",k).removeClass(h.sSortable+" "+h.sSortableAsc+" "+h.sSortableDesc+" "+h.sSortableNone),e.bJUI&&(c("th span."+h.sSortIcon+", td span."+h.sSortIcon,k).detach(),c("th, td",k).each(function(){var a=c("div."+h.sSortJUIWrapper,this);c(this).append(a.contents()),a.detach()})),!d&&g)try{g.insertBefore(i,e.nTableReinsertBefore)}catch(q){b.warn(q),g.appendChild(i)}m.css("width",e.sDestroyWidth).removeClass(h.sTable),f=e.asDestroyStripes.length,f&&n.children().each(function(a){c(this).addClass(e.asDestroyStripes[a%f])});var r=c.inArray(e,c.fn.DataTable.settings);-1!==r&&c.fn.DataTable.settings.splice(r,1)})})}]),d.module("datatables.options",[]).constant("DT_DEFAULT_OPTIONS",{dom:"lfrtip",sAjaxDataProp:"",aoColumns:[]}).service("DTDefaultOptions",function(){this.bootstrapOptions={},this.setLanguageSource=function(a){return c.extend(c.fn.dataTable.defaults,{oLanguage:{sUrl:a}}),this},this.setLanguage=function(a){return c.extend(!0,c.fn.dataTable.defaults,{oLanguage:a}),this},this.setDisplayLength=function(a){return c.extend(c.fn.dataTable.defaults,{iDisplayLength:a}),this},this.setBootstrapOptions=function(a){return this.bootstrapOptions=a,this}}),d.module("datatables.renderer",["datatables.factory","datatables.options"]).factory("DTRendererService",["DTLoadingTemplate",function(a){var b=d.element(a.html);return{getLoadingElem:function(){return b},showLoading:function(a){a.after(b),a.hide(),b.show()},hideLoading:function(a){a.show(),b.hide()},renderDataTableAndEmitEvent:function(a,b,d){var e="#"+a.attr("id");c.fn.dataTable.isDataTable(e)&&(b.destroy=!0);var f=a.DataTable(b);return d.$emit("event:dataTableLoaded",{id:a.attr("id"),DataTable:f,dataTable:a.dataTable()}),f},doRenderDataTable:function(a,b,c){return this.hideLoading(a),this.renderDataTableAndEmitEvent(a,b,c)}}}]).factory("DTRenderer",function(){return{withOptions:function(a){return this.options=a,this}}}).factory("DTDefaultRenderer",["$timeout","DTRenderer","DTRendererService",function(a,b,c){return{create:function(d){var e=Object.create(b);return e.name="DTDefaultRenderer",e.options=d,e.render=function(b,d){var e=this;return a(function(){c.doRenderDataTable(d,e.options,b)},0,!1),e},e}}}]).factory("DTNGRenderer",["$compile","$timeout","DTRenderer","DTRendererService",function(a,b,c,d){return{create:function(e){var f=Object.create(c);return f.name="DTNGRenderer",f.options=e,f.render=function(c,e,f){var g=this,h=e.find("tbody").html(),i=h.match(/^\s*.+?\s+in\s+(\S*)\s*/),j=i[1];if(!i)throw new Error('Expected expression in form of "_item_ in _collection_[ track by _id_]" but got "{0}".',h);var k,l=!1,m=c.$parent;return m.$watchCollection(j,function(){k&&l&&(k.ngDestroy(),e.html(f),a(e.contents())(m)),b(function(){l=!0,k=d.doRenderDataTable(e,g.options,c)},0,!1)},!0),g},f}}}]).factory("DTPromiseRenderer",["$timeout","DTRenderer","DTRendererService",function(a,b,c){return{create:function(e){var f,g=!1,h=function(b,d,e,g){delete e.$promise,b.aaData=e,a(function(){c.hideLoading(d),b.bDestroy=!0,f?(f.clear(),f.rows.add(b.aaData).draw()):f=c.renderDataTableAndEmitEvent(d,b,g)},0,!1)},i=Object.create(b);return i.name="DTPromiseRenderer",i.options=e,i.render=function(a,b){var c=this,e=null,f=function(d){var f=d;c.options.sAjaxDataProp&&(f=d[c.options.sAjaxDataProp]),h(c.options,b,f,a),e=null},i=function(a){e=d.isFunction(a)?a():a,e.then(f)},j=function(a){if(!d.isDefined(a))throw new Error("You must provide a promise or a function that returns a promise!");e?e.then(function(){i(a)}):i(a)};return g||(a.$watch("dtOptions.fnPromise",function(a,b){a!==b&&j(a)}),g=!0),j(a.dtOptions.fnPromise),c},i}}}]).factory("DTAjaxRenderer",["$timeout","DTRenderer","DTRendererService","DT_DEFAULT_OPTIONS",function(a,b,c,e){return{create:function(f){var g,h=function(a,b,c,e){d.isDefined(b)&&(a.sAjaxSource=b,d.isDefined(a.ajax)&&(d.isObject(a.ajax)?a.ajax.url=b:a.ajax={url:b})),i(a,c,e)},i=function(b,d,e){b.bDestroy=!0,a(function(){if(c.hideLoading(d),g){var a=b.sAjaxSource||b.ajax.url||b.ajax;g.ajax.url(a).load()}else g=c.renderDataTableAndEmitEvent(d,b,e)},0,!1)},j=Object.create(b);return j.name="DTAjaxRenderer",j.options=f,j.render=function(a,b){var c=this;return d.isUndefined(c.options.sAjaxDataProp)&&(c.options.sAjaxDataProp=e.sAjaxDataProp),d.isUndefined(c.options.aoColumns)&&(c.options.aoColumns=e.aoColumns),h(c.options,c.options.sAjaxSource,b,a),this},j}}}]).factory("DTRendererFactory",["DTDefaultRenderer","DTNGRenderer","DTPromiseRenderer","DTAjaxRenderer",function(a,b,c,e){return{fromOptions:function(f,g){return g?b.create(f):d.isDefined(f)?d.isDefined(f.fnPromise)&&null!==f.fnPromise?c.create(f):d.isDefined(f.sAjaxSource)&&null!==f.sAjaxSource||d.isDefined(f.ajax)&&null!==f.ajax?e.create(f):a.create(f):a.create()}}}]),d.module("datatables.util",[]).factory("DTPropertyUtil",function(){return{overrideProperties:function(a,b){var c=d.copy(a);if((d.isUndefined(c)||null===c)&&(c={}),d.isUndefined(b)||null===b)return c;if(d.isObject(b))for(var e in b)b.hasOwnProperty(e)&&(c[e]=this.overrideProperties(c[e],b[e]));else c=d.copy(b);return c},deleteProperty:function(a,b){d.isObject(a)&&delete a[b]}}})}(window,document,jQuery,angular); \ No newline at end of file diff --git a/src/angular-datatables.directive.js b/src/angular-datatables.directive.js index 1723b22dd..1f934ac45 100644 --- a/src/angular-datatables.directive.js +++ b/src/angular-datatables.directive.js @@ -10,13 +10,13 @@ angular.module('datatables.directive', ['datatables.renderer', 'datatables.optio dtColumnDefs: '=', datatable: '@' }, - compile: function(tElm) { + compile: function (tElm) { var _staticHTML = tElm[0].innerHTML; + return function postLink($scope, $elem, iAttrs, ctrl) { - $scope.$watch('[dtOptions, dtColumns, dtColumnDefs]', function(newVal, oldVal) { + function handleChanges(newVal, oldVal){ if (newVal !== oldVal) { - var newDTOptions = newVal[0], - oldDTOptions = oldVal[0]; + var newDTOptions = newVal[0], oldDTOptions = oldVal[0]; // Do not rerender if we want to reload. There are already // some watchers in the renderers. if (!newDTOptions.reload || newDTOptions.sAjaxSource !== oldDTOptions.sAjaxSource) { @@ -27,7 +27,14 @@ angular.module('datatables.directive', ['datatables.renderer', 'datatables.optio newDTOptions.reload = false; } } - }, true); + } + + // Options can hold heavy data, and other deep/large objects. + // watchcollection can improve this by only watching shallowly + var watchFunction = iAttrs.disableDeepWatchers ? '$watchCollection' : '$watch'; + angular.forEach(['dtColumns', 'dtColumnDefs', 'dtOptions'], function(tableDefField){ + $scope[watchFunction].call($scope, tableDefField, handleChanges, true); + }); ctrl.showLoading($elem); ctrl.render($elem, ctrl.buildOptionsPromise(), _staticHTML); };