Friday, May 16, 2014

consolidate Ajax Call

Suppose there is an ajax call which is issued each time when user is typing a character in a text box. If the end user types 10 characters, there will be 10 ajax call. However, only the result from last one is used by application. It is really wasteful to make the other 9 calls.

Here is one approach how you can cancel the uncessary ajax call. I am using $timeout service in angularjs. You can use standard timeout API.

$scope.ajaxcall=null;

if ($scope.ajaxcall!==null) {
 $timeout.cancel($scope.ajaxcall);
}
$scope.ajaxcall=$timeout(function() {
// my ajaxcall here
}, 300);


Here is all ajax call is queued by timeout. If the next call found an invoked call, it cancels the previous one. Of course, if the call is already made, the cancellation has no effects. If the end user types rapidly and do not care the intermediate results, you can cancel most of the unnecessary ajax call.


Dynamic Template for AngularJS

How can you use a context-dependent template?

Use ngInclude

<ng-include src="'mytemplate.html'"/>
Here the src for ngInclude is an expression. Here I use a static template file so it is a string quoted with single quote here. You can set use an expression instead of static string. The expression can be set up in parent scope/context, so the  template is dynamic.
E.G
<ng-include src="getMyTemplate(param)"/>

Use $compile in link function of directive

You can use this if you template is really dynamic and composed from various sources. You use the link function in a directive to manipulate the html.
E.g
instApp.directive("fxRelationEditor", function($compile, $templateCache){
    return {
        restrict:'E',

      link: function($scope, $element, $attrs, $templateCache){
            var topelement=angular.element($templateCache.get("template/report/relation_editor_top.html"));
            if ($scope.relationui.showselected){
                topelement.find(".selected").html($templateCache.get("template/report/relation_editor_showselected.html"));
            }
            var editorhtml=flexdms.query.originalrelationeditor;
            /
            //no report, default ui.
            if (!$scope.relationui.report){
                editorhtml=flexdms.query.originalrelationeditor
                topelement.find(".editor").html(editorhtml);
                $element.html(topelement.get(0).outerHTML);
                $compile($element.contents())($scope);
                return;
            }
            ...

}
};
});

In the example above, we create a DOM element dynamically from various sources and set it as new template.