{"id":51843,"date":"2013-08-29T13:16:06","date_gmt":"2013-08-29T10:16:06","guid":{"rendered":"https:\/\/www.altoros.com\/blog\/?p=51843"},"modified":"2020-04-06T11:39:58","modified_gmt":"2020-04-06T08:39:58","slug":"evaluation-of-angularjs-a-javascript-ui-framework","status":"publish","type":"post","link":"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/","title":{"rendered":"Evaluation of AngularJS, a JavaScript UI Framework"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_79_2 counter-hierarchy ez-toc-counter ez-toc-transparent ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#Rapid_development\" >Rapid development<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#Extending_HTML_capabilities_with_Directives\" >Extending HTML capabilities with Directives<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#Testing\" >Testing<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#Filtering\" >Filtering<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#Dependency_injection\" >Dependency injection<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#Form_validation\" >Form validation<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#The_template_engine\" >The template engine<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#Integrations_and_compatibility\" >Integrations and compatibility<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#Conclusion\" >Conclusion<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-3'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#Further_reading\" >Further reading<\/a><\/li><\/ul><\/nav><\/div>\n<h3><span class=\"ez-toc-section\" id=\"Rapid_development\"><\/span>Rapid development<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>During the last two months, the team at Altoros has been using <a href=\"https:\/\/angularjs.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">AngularJS<\/a>, a JavaScript UI framework, to develop a user interface for the next-generation document management system. The experts also utilized <a href=\"https:\/\/gruntjs.com\/\" target=\"_blank\" rel=\"noopener noreferrer\">Grunt <\/a>for building a client application and <a href=\"http:\/\/karma-runner.github.io\/\" target=\"_blank\" rel=\"noopener noreferrer\">Karma <\/a>for automating unit tests. The back-end part was developed with the Java technology stack.<\/p>\n<p>With this tool, JavaScript development becomes really fast. A single person can bring out 1\u20132 significant features a day. Not less important, AngularJS is also good for prototyping. This framework makes it possible to find the right balance between code quality and velocity of the development process.<\/p>\n<p>If you are a novice to AngularJS, you can start with <a href=\"http:\/\/angular-tips.com\/blog\/2013\/08\/why-does-angular-dot-js-rock\/\" target=\"_blank\" rel=\"noopener noreferrer\">this introduction article<\/a>. This article provides a short overview of the main AngularJS features and shares tips on how to fix some issues.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Extending_HTML_capabilities_with_Directives\"><\/span>Extending HTML capabilities with Directives<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>AngularJS comes with a set of built-in directives that allow for creating custom HTML elements and modifying the behavior of DOM elements. It can be quite useful for building complex front ends. Isolated scopes enable developers to divide data and use a particular portion of this data when necessary. One of the main documentation drawbacks is that it provides just a few examples of how to work with directives and scopes. So, we had to use these components intuitively.<\/p>\n<p>However, you should be very careful while playing with them, since they may cause a lot of issues. For instance, the documentation says that a directive scope in AngularJS may be a child to the parent scope through the prototype-based JavaScript inheritance. In this case, parent scope variables will only be available for reading. Our team spent quite a lot of time investigating different parts of the application to find out how it really works. Eventually, we discovered a very useful tool for resolving issues like that\u2014<a href=\"https:\/\/github.com\/angular\/batarang\" target=\"_blank\" rel=\"noopener noreferrer\">AngularJS WebInspector Extension for Chrome<\/a>. It is a browser plug-in that allows for navigating through the hierarchy of AngularJS scopes.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Testing\"><\/span>Testing<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>The testing of applications in AngularJS is simple and intuitive.<\/p>\n<p><strong>Unit tests<\/strong><\/p>\n<p>We created the following unit tests to check the system\u2019s models.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ndescribe(\u2018Tabs control\u2019, function() {\r\n    var model;\r\n\r\n    beforeEach(module(\u2018mycontrol\u2019));\r\n    beforeEach(inject(function(MyControlModel) {\r\n         model = new MyControlModel();\r\n    }));\r\n\r\n    it(\u2018should allow to add new element\u2019, function () {\r\n         model.add({name: \u2018Header\u2019});\r\n         expect(model.elements.length).toBe(1);\r\n    });\r\n});\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Integration tests<\/strong><\/p>\n<p>AngularJS unit test libraries enable to create integration tests as well. As for our system, we developed a directive that represented a page and then triggered the events, using jQuery. After that, the markup and state of the models were verified. We mocked the calls to the REST API with the \u201c$httpBackend\u201d service.<\/p>\n<p>With this approach, smoke tests were completed just in five seconds. However, some specific features of Jasmine, a behavior-driven development framework for testing a JavaScript code, became a stumbling block. As it turned out, it does not allow for creating a single fixture per test suite. This feature is required to reduce the duration of tests on big components. To overcome this limitation, we created all tests in a single \u201cit\u201d function.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ndescribe(\u2018Tabs control\u2019, function() {\r\n    var control;\r\n    var scope;\r\n\r\n    beforeEach(module(\u2018mycontrol\u2019));\r\n    beforeEach(inject(function($compile, $rootScope, $httpBackend) {\r\n         \/\/ create custom directive with model\r\n         scope = $rootScope.$new();\r\n         control = $compile(\u2018&amp;lt;control&amp;gt;&amp;lt;\/control&amp;gt;\u2019)(scope);\r\n\r\n         \/\/ mock some backend calls\r\n         $httpBackend\r\n             .when(\u2018GET\u2019, \u2018\/api\/resources\u2019)\r\n             .respond(&#x5B;{name: \u2018name1\u2019, data: \u2018other_data\u2019}]);\r\n    }));\r\n\r\n    it(\u2018should allow to add new element\u2019, function () {\r\n         $(control).find(\u2018button.add\u2019).click();\r\n         expect($(control).find(\u2018table tr\u2019).length).toBe(1);\r\n    });\r\n});\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>End-to-end tests<\/strong><\/p>\n<p>As it was previously mentioned, we used Grunt to build a client. It has the \u201cwatch\u201d feature that starts tests, when some changes are made to the code. To test the application on servers that have no graphical user interface, <a href=\"https:\/\/phantomjs.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">PhantomJS<\/a> was used. All the technologies described above are very efficient together.<\/p>\n<p>Another AngularJS feature is black-box testing of user interfaces with JavaScript. However, we decided to skip it. If used it, we would need to create a separate web page with the mocked back end to carry out these tests. In our case, it would make the back-end part of the system more complicated. Furthermore, we would be unable to distinctively separate the test code from the production code.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Filtering\"><\/span>Filtering<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>AngularJS is very declarative and functional. Pure functions, closures, and the currying method are widely used when working with this framework.<\/p>\n<p>The template engine introduces a new intriguing concept of filters. It resembles map functions with the syntax inherited from Linux shell streams. With the two-way binding of scopes, this feature allows for implementing amazing functions very fast. These filters enabled us to easily create lookups\u2014reusable lists of key-value pairs in drop-down menus.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nfilter(\u2018lookup\u2019, &#x5B;function () {\r\n    var LOOKUPS = {\r\n        USERS: {\r\n            NEW: \u2018New User\u2019,\r\n            EDIT: \u2018Edit User\u2019\r\n        }\r\n    };\r\n    return function (input, lookupName) {\r\n        return LOOKUPS&#x5B;lookupName]&#x5B;input];\r\n    }\r\n}])\r\n\r\n&lt;div ng-init=\u201dfoo = \u2018NEW\u2019\u201d&gt; &lt;!-- Key of lookup value --&gt;\r\n{{ foo | lookup:\u2019USERS\u2019 }} &lt;!--  Will be rendered \u2018New User\u2019\u2019 --&gt;\r\n&lt;\/div&gt;\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Dependency_injection\"><\/span>Dependency injection<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>AngularJS has a built-in dependency injection (DI) engine. Compared to pure jQuery, AngularJS provides better isolation of modules, as developers should spend less time reviewing the legacy code after adding new features. With this pattern, we were able to minimize the impact of the changed code on the entire system.<\/p>\n<p>However, the DI engine may be not suitable in some cases. For instance, to create a constructor, we needed to develop a separate module, give it a name, and specify this name in the code each time the constructor was used. It is much more time-consuming than just to create a namespace that will automatically insert a constructor everywhere we need it. We tried to find a way to bring this functionality to the AngularJS DI engine but did not come across an acceptable option.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Form_validation\"><\/span>Form validation<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Validators usually need customization. Since forms and validators are very flexible in AngularJS, you will be able to create an editable table with minimum efforts. Below is a simple example of a form validation.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&lt;form ng-app=&quot;miniapp&quot; name=&quot;miniform&quot; novalidate&gt; \r\n    &lt;div ng-controller=&quot;Ctrl&quot;&gt;\r\n        &lt;input name=&quot;field&quot; type=&quot;text&quot; ng-model=&quot;value&quot; number=&quot;&quot; \/&gt;\r\n        &lt;span ng-show=&quot;miniform.field.$error.number&quot;&gt;Field must contains number&lt;\/span&gt;\r\n    &lt;\/div&gt;\r\n&lt;\/form&gt;\r\n\r\nangular.module('miniapp', &#x5B;])\r\n\r\n    .controller('Ctrl', function ($scope) {\r\n        $scope.value = '';\r\n    })\r\n\r\n    .directive('number', function () {\r\n        return {\r\n            require: 'ngModel',\r\n            link: function (scope, elm, attrs, ctrl) {\r\n                ctrl.$parsers.unshift(function (viewValue) {\r\n                    var isEmpty = viewValue === '';\r\n                    var isNumber = !isNaN(parseInt(viewValue, 10));\r\n                    ctrl.$setValidity('number', isEmpty || isNumber);\r\n                    return viewValue;\r\n                });\r\n            }\r\n        };\r\n    });\r\n<\/pre>\n<p>You can play with this code on <a href=\"http:\/\/jsfiddle.net\/geZB5\/6\/\" target=\"_blank\" rel=\"noopener noreferrer\">jsFiddle<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"The_template_engine\"><\/span>The template engine<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Although the engine supports HTML tags, we experienced certain issues with some of the tags while working with custom directives.<\/p>\n<p>Another issue is that some standard AngularJS tags create new scopes, since a parent scope is only accessible while reading.<\/p>\n<p>In addition, it is not that easy to develop custom directives. AngularJS does not support directive inheritance, as a result, the code is duplicated. Nevertheless, the composition of components looks really great.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Integrations_and_compatibility\"><\/span>Integrations and compatibility<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Sometimes it can be tricky to integrate AngularJS with jQuery plug-ins. We experienced memory leaks and spent a lot of time on fixing this. However, there is a way to easily eliminate these leaks. You just need to delete jQuery plug-in variables when deleting AngularJS scopes.<\/p>\n<p>The front end of our system was developed for IE8. To provide support for earlier versions of IE, we used the <a href=\"https:\/\/github.com\/afarkas\/html5shiv\" target=\"_blank\" rel=\"noopener noreferrer\">html5shiv<\/a> script.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<p>Being well-architected, AngularJS speeds up front-end development and provides almost enterprise-level testing capabilities. This framework has better memory management than Backbone.js, supports form validation that <a href=\"https:\/\/www.altoros.com\/blog\/diving-into-ember-js-part-1-2\/\">Ember.js<\/a> lacks, and allows for more flexible customization of components compared to Ext JS. With AngularJS, it will be easy for you to properly organize your web applications.<\/p>\n<p>&nbsp;<\/p>\n<h3><span class=\"ez-toc-section\" id=\"Further_reading\"><\/span>Further reading<span class=\"ez-toc-section-end\"><\/span><\/h3>\n<ul>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/how-to-speed-up-angularjs-apps-that-use-internalization-libraries\/#more-5021\">How to Speed Up AngularJS Apps That Use Internalization Libraries<\/a><\/li>\n<li><a href=\"https:\/\/www.altoros.com\/blog\/data-visualization-tools-flot-vs-highcharts-vs-d3-js\/\">Data Visualization Tools: Flot vs. Highcharts vs. D3.js<\/a><\/li>\n<li><a href=\"https:\/\/blog.altoros.com\/flash-vs-html5-how-to-%d1%81onvert-and-what-to-expect-in-future.html\">Flash vs. HTML5: How to \u0421onvert and What to Expect in the Future?<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Rapid development<\/p>\n<p>During the last two months, the team at Altoros has been using AngularJS, a JavaScript UI framework, to develop a user interface for the next-generation document management system. The experts also utilized Grunt for building a client application and Karma for automating unit tests. The back-end part was developed [&#8230;]<\/p>\n","protected":false},"author":71,"featured_media":51848,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":"","_links_to":"","_links_to_target":""},"categories":[7],"tags":[895],"class_list":["post-51843","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news-and-opinion","tag-research-and-development"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Evaluation of AngularJS, a JavaScript UI Framework | Altoros<\/title>\n<meta name=\"description\" content=\"The blog post overviews the main AngularJS features, as well as provides tips on how to fix some issues while developing web applications.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Evaluation of AngularJS, a JavaScript UI Framework | Altoros\" \/>\n<meta property=\"og:description\" content=\"Rapid development During the last two months, the team at Altoros has been using AngularJS, a JavaScript UI framework, to develop a user interface for the next-generation document management system. The experts also utilized Grunt for building a client application and Karma for automating unit tests. The back-end part was developed [...]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/\" \/>\n<meta property=\"og:site_name\" content=\"Altoros\" \/>\n<meta property=\"article:published_time\" content=\"2013-08-29T10:16:06+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-04-06T08:39:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2013\/08\/evaluation-of-angularjs-featured-image.png\" \/>\n\t<meta property=\"og:image:width\" content=\"640\" \/>\n\t<meta property=\"og:image:height\" content=\"360\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Ilya Drabenia\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ilya Drabenia\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/\",\"name\":\"Evaluation of AngularJS, a JavaScript UI Framework | Altoros\",\"isPartOf\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2013\/08\/evaluation-of-angularjs-featured-image.png\",\"datePublished\":\"2013-08-29T10:16:06+00:00\",\"dateModified\":\"2020-04-06T08:39:58+00:00\",\"author\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/48c2eaf6d86abc9fa945bc3860fa2dc2\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#primaryimage\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2013\/08\/evaluation-of-angularjs-featured-image.png\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2013\/08\/evaluation-of-angularjs-featured-image.png\",\"width\":640,\"height\":360},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.altoros.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Evaluation of AngularJS, a JavaScript UI Framework\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#website\",\"url\":\"https:\/\/www.altoros.com\/blog\/\",\"name\":\"Altoros\",\"description\":\"Insight\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.altoros.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/48c2eaf6d86abc9fa945bc3860fa2dc2\",\"name\":\"Ilya Drabenia\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/01\/1108467-150x150.jpg\",\"contentUrl\":\"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/01\/1108467-150x150.jpg\",\"caption\":\"Ilya Drabenia\"},\"description\":\"Ilya Drabenia is a Technical Lead at Altoros. He has broad experience in building software architectures, including design and development of complex solutions. Ilya is passionate about microservices, domain-driven design, as well as scalable and parallel algorithms. He also holds an MSc degree in Computer Science. See his profile on GitHub.\",\"url\":\"https:\/\/www.altoros.com\/blog\/author\/ilya-drabenia\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Evaluation of AngularJS, a JavaScript UI Framework | Altoros","description":"The blog post overviews the main AngularJS features, as well as provides tips on how to fix some issues while developing web applications.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/","og_locale":"en_US","og_type":"article","og_title":"Evaluation of AngularJS, a JavaScript UI Framework | Altoros","og_description":"Rapid development During the last two months, the team at Altoros has been using AngularJS, a JavaScript UI framework, to develop a user interface for the next-generation document management system. The experts also utilized Grunt for building a client application and Karma for automating unit tests. The back-end part was developed [...]","og_url":"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/","og_site_name":"Altoros","article_published_time":"2013-08-29T10:16:06+00:00","article_modified_time":"2020-04-06T08:39:58+00:00","og_image":[{"width":640,"height":360,"url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2013\/08\/evaluation-of-angularjs-featured-image.png","type":"image\/png"}],"author":"Ilya Drabenia","twitter_misc":{"Written by":"Ilya Drabenia","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/","url":"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/","name":"Evaluation of AngularJS, a JavaScript UI Framework | Altoros","isPartOf":{"@id":"https:\/\/www.altoros.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#primaryimage"},"image":{"@id":"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#primaryimage"},"thumbnailUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2013\/08\/evaluation-of-angularjs-featured-image.png","datePublished":"2013-08-29T10:16:06+00:00","dateModified":"2020-04-06T08:39:58+00:00","author":{"@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/48c2eaf6d86abc9fa945bc3860fa2dc2"},"breadcrumb":{"@id":"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#primaryimage","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2013\/08\/evaluation-of-angularjs-featured-image.png","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2013\/08\/evaluation-of-angularjs-featured-image.png","width":640,"height":360},{"@type":"BreadcrumbList","@id":"https:\/\/www.altoros.com\/blog\/evaluation-of-angularjs-a-javascript-ui-framework\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.altoros.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Evaluation of AngularJS, a JavaScript UI Framework"}]},{"@type":"WebSite","@id":"https:\/\/www.altoros.com\/blog\/#website","url":"https:\/\/www.altoros.com\/blog\/","name":"Altoros","description":"Insight","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.altoros.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/48c2eaf6d86abc9fa945bc3860fa2dc2","name":"Ilya Drabenia","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.altoros.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/01\/1108467-150x150.jpg","contentUrl":"https:\/\/www.altoros.com\/blog\/wp-content\/uploads\/2017\/01\/1108467-150x150.jpg","caption":"Ilya Drabenia"},"description":"Ilya Drabenia is a Technical Lead at Altoros. He has broad experience in building software architectures, including design and development of complex solutions. Ilya is passionate about microservices, domain-driven design, as well as scalable and parallel algorithms. He also holds an MSc degree in Computer Science. See his profile on GitHub.","url":"https:\/\/www.altoros.com\/blog\/author\/ilya-drabenia\/"}]}},"_links":{"self":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/51843","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/users\/71"}],"replies":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/comments?post=51843"}],"version-history":[{"count":12,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/51843\/revisions"}],"predecessor-version":[{"id":52696,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/posts\/51843\/revisions\/52696"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media\/51848"}],"wp:attachment":[{"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/media?parent=51843"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/categories?post=51843"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.altoros.com\/blog\/wp-json\/wp\/v2\/tags?post=51843"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}