Are you over 18 and want to see adult content?
More Annotations
A complete backup of safetydevices.com
Are you over 18 and want to see adult content?
A complete backup of estudiodeinterioresmyp.com
Are you over 18 and want to see adult content?
A complete backup of gebraucht-kaufen.de
Are you over 18 and want to see adult content?
A complete backup of corsica-productions.com
Are you over 18 and want to see adult content?
Favourite Annotations
A complete backup of www.xhamsterlive.com
Are you over 18 and want to see adult content?
A complete backup of badgirlsblog.com
Are you over 18 and want to see adult content?
A complete backup of www.enf-cmnf.com
Are you over 18 and want to see adult content?
A complete backup of www.aerisdies.com
Are you over 18 and want to see adult content?
Text
CLIFF MEYERS
I've built a very basic "Reddit Browser" AngularJS application that provides a working sample of these techniques. The code is available on Github here: "blog-examples" repository. Clone the repo and then start the Node web server script using: ./scripts/web-server.js. ABOUT — CLIFF MEYERS The year is 2021. We are flying spacecraft on Mars, yet Google Analytics doesn't have out-of-the-box support for Si https://t.co/c9wR212cIz CONTACT — CLIFF MEYERS The year is 2021. We are flying spacecraft on Mars, yet Google Analytics doesn't have out-of-the-box support for Si https://t.co/c9wR212cIzCLIFF MEYERS
Spring comes with some extremely useful convenience classes for test automation using JUnit. In order to use them, be sure to add the spring-mock.jar to your project.CLIFF MEYERS
Fortunately I was able to hack together a quick and dirty workaround for this based off Hogan.js, Twitter's Mustache-compatible HTML templating system. First I wrote a simple HTML template named myTemplate.mustache: Then I used Hogan's "hulk" executable to compile the template to a Javascript file. If you have multiple templates,hulk will
CLIFF MEYERS
The other day I threw together a quick proof-of-concept for integrating AngularJS with the jQuery Globalize Plugin.The first part is a simple utility Angular "service" which CODE ORGANIZATION IN LARGE ANGULARJS AND JAVASCRIPT Code Organization in Large AngularJS and JavaScript Applications. Many developers struggle with how to organize an application's code base once it grows in size. I've seen this recently in AngularJS and JavaScript applications but historically it's been a problem across all technologies including many Java and Flex apps I've worked on inthe past.
MIXING AND MATCHING SPRING JDBCTEMPLATE AND Mixing and Matching Spring JdbcTemplate and HibernateTemplate. The JdbcTemplate and HibernateTemplate convenience classes from Spring really make working with the respective APIs a breeze. Unfortunately getting both of these classes to work together within a single Transaction is not straightforward. This comes up very frequently inJUnit tests
INTEGRATING ANGULARJS AND I18N-JS, SWITCHING LOCALES AT Integrating AngularJS and i18n-js, Switching Locales at Runtime. AngularJS has really nice built-in support for number, currency and date formatting. Unfortunately it lacks two significant features: Performing string lookup / interpolation via externalized message bundles, and. Allowing the application to change the current locale atruntime.
SPRING AOP: CGLIB OR JDK DYNAMIC PROXIES? Spring can use two. different techniques for creating proxies at runtime: CGLIB or JDK dynamic proxies. If the target class implements one or more interfaces, then Spring will create a JDK dynamic proxy that implements every interface. If the target class implements no interfaces, Spring will use CGLIB to create a new class on the flythat is a
CLIFF MEYERS
I've built a very basic "Reddit Browser" AngularJS application that provides a working sample of these techniques. The code is available on Github here: "blog-examples" repository. Clone the repo and then start the Node web server script using: ./scripts/web-server.js. ABOUT — CLIFF MEYERS The year is 2021. We are flying spacecraft on Mars, yet Google Analytics doesn't have out-of-the-box support for Si https://t.co/c9wR212cIz CONTACT — CLIFF MEYERS The year is 2021. We are flying spacecraft on Mars, yet Google Analytics doesn't have out-of-the-box support for Si https://t.co/c9wR212cIzCLIFF MEYERS
Spring comes with some extremely useful convenience classes for test automation using JUnit. In order to use them, be sure to add the spring-mock.jar to your project.CLIFF MEYERS
Fortunately I was able to hack together a quick and dirty workaround for this based off Hogan.js, Twitter's Mustache-compatible HTML templating system. First I wrote a simple HTML template named myTemplate.mustache: Then I used Hogan's "hulk" executable to compile the template to a Javascript file. If you have multiple templates,hulk will
CLIFF MEYERS
The other day I threw together a quick proof-of-concept for integrating AngularJS with the jQuery Globalize Plugin.The first part is a simple utility Angular "service" which CODE ORGANIZATION IN LARGE ANGULARJS AND JAVASCRIPT Code Organization in Large AngularJS and JavaScript Applications. Many developers struggle with how to organize an application's code base once it grows in size. I've seen this recently in AngularJS and JavaScript applications but historically it's been a problem across all technologies including many Java and Flex apps I've worked on inthe past.
MIXING AND MATCHING SPRING JDBCTEMPLATE AND Mixing and Matching Spring JdbcTemplate and HibernateTemplate. The JdbcTemplate and HibernateTemplate convenience classes from Spring really make working with the respective APIs a breeze. Unfortunately getting both of these classes to work together within a single Transaction is not straightforward. This comes up very frequently inJUnit tests
INTEGRATING ANGULARJS AND I18N-JS, SWITCHING LOCALES AT Integrating AngularJS and i18n-js, Switching Locales at Runtime. AngularJS has really nice built-in support for number, currency and date formatting. Unfortunately it lacks two significant features: Performing string lookup / interpolation via externalized message bundles, and. Allowing the application to change the current locale atruntime.
SPRING AOP: CGLIB OR JDK DYNAMIC PROXIES? Spring can use two. different techniques for creating proxies at runtime: CGLIB or JDK dynamic proxies. If the target class implements one or more interfaces, then Spring will create a JDK dynamic proxy that implements every interface. If the target class implements no interfaces, Spring will use CGLIB to create a new class on the flythat is a
CLIFF MEYERS
HFCD is an extension for Flash/Flex Builder that delegates compilation of your Flex application to a special "compiler daemon" which can run locally or on a remote machine. The goal of the project is simple: faster builds! HFCD is the brainchild of Clement Wong, the former compiler engineering lead on the Flex SDK team.Here are a few useful things to understand about HFCD:CLIFF MEYERS
If you're looking for the short answer, go check out the Spring Data JPA project. This is an incredible product that offers a tremendous productivity boost for projects using JPA.CLIFF MEYERS
Fortunately I was able to hack together a quick and dirty workaround for this based off Hogan.js, Twitter's Mustache-compatible HTML templating system. First I wrote a simple HTML template named myTemplate.mustache: Then I used Hogan's "hulk" executable to compile the template to a Javascript file. If you have multiple templates,hulk will
CLIFF MEYERS
I've been working with Sencha Touch lately and I've been impressed with it so far. It's a really nice full-stack solution for HTML5 mobile web development.CLIFF MEYERS
This is the second entry in a multi-part series about localization. Every modern platform provides a mechanism for formatting dates. We've all dealt with people on the business side who prefer dates formatted as YYYY-mm-dd or dd MMM YY or countless other permutations. BOOK REVIEW: THE DEFINITIVE GUIDE TO TERRACOTTA Terracotta is a “transparent clustering technology” that allows you to make data structures available across a cluster of machines in a highly-scalable and robust manner. Unlike many other clustering solutions (including the very popular memcached), it doesn’t exposean API that a
ON HIBERNATE, SPRING, SESSIONS AND TRANSACTIONS I was recently working with Spring and Hibernate on a pet project and ran into some issues with Session and Transaction management that proved to be pretty interesting in the end. The following assumes a working knowledge of Hibernate and Spring I was in the midst of writing some JUnit 4.x tes STARTING WITH GIT AND GITHUB ON WINDOWS My attempt at a very brief tutorial for starting with Git on Windows: Head over to http://github.com and create an account. Create a new repository next. Please WHY I FINALLY DITCHED HIBERNATE NATIVE APIS FOR JPA If you're looking for the short answer, go check out the Spring Data JPA project. This is an incredible product that offers a tremendous productivity boost for projects using JPA. If you're interested in the more gory details, read on below :) I've been a Hibernate user since INTEGRATING BLAZE DATA SERVICES AND SPRING SECURITY One thing to keep in mind with the out-of-the-box security support in Blaze DS is the approach to integration is container-specific: there is support for Tomcat (and therefore JBoss), WebSphere, Weblogic and Oracle through various implementations of the LoginCommand interface. Unfortunately if you hCLIFF MEYERS
I've built a very basic "Reddit Browser" AngularJS application that provides a working sample of these techniques. The code is available on Github here: "blog-examples" repository. Clone the repo and then start the Node web server script using: ./scripts/web-server.js. ABOUT — CLIFF MEYERS The year is 2021. We are flying spacecraft on Mars, yet Google Analytics doesn't have out-of-the-box support for Si https://t.co/c9wR212cIz CONTACT — CLIFF MEYERS The year is 2021. We are flying spacecraft on Mars, yet Google Analytics doesn't have out-of-the-box support for Si https://t.co/c9wR212cIzCLIFF MEYERS
Spring comes with some extremely useful convenience classes for test automation using JUnit. In order to use them, be sure to add the spring-mock.jar to your project.CLIFF MEYERS
Fortunately I was able to hack together a quick and dirty workaround for this based off Hogan.js, Twitter's Mustache-compatible HTML templating system. First I wrote a simple HTML template named myTemplate.mustache: Then I used Hogan's "hulk" executable to compile the template to a Javascript file. If you have multiple templates,hulk will
CLIFF MEYERS
The other day I threw together a quick proof-of-concept for integrating AngularJS with the jQuery Globalize Plugin.The first part is a simple utility Angular "service" which CODE ORGANIZATION IN LARGE ANGULARJS AND JAVASCRIPT Code Organization in Large AngularJS and JavaScript Applications. Many developers struggle with how to organize an application's code base once it grows in size. I've seen this recently in AngularJS and JavaScript applications but historically it's been a problem across all technologies including many Java and Flex apps I've worked on inthe past.
MIXING AND MATCHING SPRING JDBCTEMPLATE AND Mixing and Matching Spring JdbcTemplate and HibernateTemplate. The JdbcTemplate and HibernateTemplate convenience classes from Spring really make working with the respective APIs a breeze. Unfortunately getting both of these classes to work together within a single Transaction is not straightforward. This comes up very frequently inJUnit tests
INTEGRATING ANGULARJS AND I18N-JS, SWITCHING LOCALES AT Integrating AngularJS and i18n-js, Switching Locales at Runtime. AngularJS has really nice built-in support for number, currency and date formatting. Unfortunately it lacks two significant features: Performing string lookup / interpolation via externalized message bundles, and. Allowing the application to change the current locale atruntime.
SPRING AOP: CGLIB OR JDK DYNAMIC PROXIES? Spring can use two. different techniques for creating proxies at runtime: CGLIB or JDK dynamic proxies. If the target class implements one or more interfaces, then Spring will create a JDK dynamic proxy that implements every interface. If the target class implements no interfaces, Spring will use CGLIB to create a new class on the flythat is a
CLIFF MEYERS
I've built a very basic "Reddit Browser" AngularJS application that provides a working sample of these techniques. The code is available on Github here: "blog-examples" repository. Clone the repo and then start the Node web server script using: ./scripts/web-server.js. ABOUT — CLIFF MEYERS The year is 2021. We are flying spacecraft on Mars, yet Google Analytics doesn't have out-of-the-box support for Si https://t.co/c9wR212cIz CONTACT — CLIFF MEYERS The year is 2021. We are flying spacecraft on Mars, yet Google Analytics doesn't have out-of-the-box support for Si https://t.co/c9wR212cIzCLIFF MEYERS
Spring comes with some extremely useful convenience classes for test automation using JUnit. In order to use them, be sure to add the spring-mock.jar to your project.CLIFF MEYERS
Fortunately I was able to hack together a quick and dirty workaround for this based off Hogan.js, Twitter's Mustache-compatible HTML templating system. First I wrote a simple HTML template named myTemplate.mustache: Then I used Hogan's "hulk" executable to compile the template to a Javascript file. If you have multiple templates,hulk will
CLIFF MEYERS
The other day I threw together a quick proof-of-concept for integrating AngularJS with the jQuery Globalize Plugin.The first part is a simple utility Angular "service" which CODE ORGANIZATION IN LARGE ANGULARJS AND JAVASCRIPT Code Organization in Large AngularJS and JavaScript Applications. Many developers struggle with how to organize an application's code base once it grows in size. I've seen this recently in AngularJS and JavaScript applications but historically it's been a problem across all technologies including many Java and Flex apps I've worked on inthe past.
MIXING AND MATCHING SPRING JDBCTEMPLATE AND Mixing and Matching Spring JdbcTemplate and HibernateTemplate. The JdbcTemplate and HibernateTemplate convenience classes from Spring really make working with the respective APIs a breeze. Unfortunately getting both of these classes to work together within a single Transaction is not straightforward. This comes up very frequently inJUnit tests
INTEGRATING ANGULARJS AND I18N-JS, SWITCHING LOCALES AT Integrating AngularJS and i18n-js, Switching Locales at Runtime. AngularJS has really nice built-in support for number, currency and date formatting. Unfortunately it lacks two significant features: Performing string lookup / interpolation via externalized message bundles, and. Allowing the application to change the current locale atruntime.
SPRING AOP: CGLIB OR JDK DYNAMIC PROXIES? Spring can use two. different techniques for creating proxies at runtime: CGLIB or JDK dynamic proxies. If the target class implements one or more interfaces, then Spring will create a JDK dynamic proxy that implements every interface. If the target class implements no interfaces, Spring will use CGLIB to create a new class on the flythat is a
CLIFF MEYERS
HFCD is an extension for Flash/Flex Builder that delegates compilation of your Flex application to a special "compiler daemon" which can run locally or on a remote machine. The goal of the project is simple: faster builds! HFCD is the brainchild of Clement Wong, the former compiler engineering lead on the Flex SDK team.Here are a few useful things to understand about HFCD:CLIFF MEYERS
If you're looking for the short answer, go check out the Spring Data JPA project. This is an incredible product that offers a tremendous productivity boost for projects using JPA.CLIFF MEYERS
Fortunately I was able to hack together a quick and dirty workaround for this based off Hogan.js, Twitter's Mustache-compatible HTML templating system. First I wrote a simple HTML template named myTemplate.mustache: Then I used Hogan's "hulk" executable to compile the template to a Javascript file. If you have multiple templates,hulk will
CLIFF MEYERS
I've been working with Sencha Touch lately and I've been impressed with it so far. It's a really nice full-stack solution for HTML5 mobile web development.CLIFF MEYERS
This is the second entry in a multi-part series about localization. Every modern platform provides a mechanism for formatting dates. We've all dealt with people on the business side who prefer dates formatted as YYYY-mm-dd or dd MMM YY or countless other permutations. BOOK REVIEW: THE DEFINITIVE GUIDE TO TERRACOTTA Terracotta is a “transparent clustering technology” that allows you to make data structures available across a cluster of machines in a highly-scalable and robust manner. Unlike many other clustering solutions (including the very popular memcached), it doesn’t exposean API that a
ON HIBERNATE, SPRING, SESSIONS AND TRANSACTIONS I was recently working with Spring and Hibernate on a pet project and ran into some issues with Session and Transaction management that proved to be pretty interesting in the end. The following assumes a working knowledge of Hibernate and Spring I was in the midst of writing some JUnit 4.x tes STARTING WITH GIT AND GITHUB ON WINDOWS My attempt at a very brief tutorial for starting with Git on Windows: Head over to http://github.com and create an account. Create a new repository next. Please WHY I FINALLY DITCHED HIBERNATE NATIVE APIS FOR JPA If you're looking for the short answer, go check out the Spring Data JPA project. This is an incredible product that offers a tremendous productivity boost for projects using JPA. If you're interested in the more gory details, read on below :) I've been a Hibernate user since INTEGRATING BLAZE DATA SERVICES AND SPRING SECURITY One thing to keep in mind with the out-of-the-box security support in Blaze DS is the approach to integration is container-specific: there is support for Tomcat (and therefore JBoss), WebSphere, Weblogic and Oracle through various implementations of the LoginCommand interface. Unfortunately if you h* Blog
* About
* Contact
CLIFF MEYERS
* Blog
* About
* Contact
MOCKING SERVER DEPENDENCIES IN JAVASCRIPT AND ANGULARJS APPLICATIONS Most Single Page Applications (SPA) written in HTML and JavaScript interact with server side code using the familar XMLHttpRequest object. During development it can be convenient to run the application with mock data that eliminates this server dependency. This can be useful if the server side stack is complex and not easy to set up on a local machine or if a shared dev server running the server components suddenly goes offline. It's also handy for tweaking the data returned by the services to ensure the UI behaves appropriately in specific scenarios. Naturally it's imperative to integrate the SPA with real server code early and often but the flexibility provided by the "server mock" technique can be indispensible. NOTE: while this article will illustrate how to mock services in an AngularJS application, this pattern applies to any UI technology (JavaScript or otherwise). The key is achieving Separation of Concerns (SoC) that allows real services and mock services to be easilyswapped.
UPDATE 12 SEPTEMBER 2013: some folks have inquired why I didn't use RESTangular in this blog. I think RESTangular is a fine framework that is more flexible than Angular's $resource abstraction. However, for simple sample code it makes more sense to use $http since more folks are familiar with it. Also, the question misses the main point of this blog post which is APPLYING A PATTERN SO DATA ACCESS CODE IS ABSTRACTED, THEREBY SIMPLIFYING THE CONTROLLER CODE. If your application grows and requires new code to implement custom caching or request queueing logic, the Repository will be the perfect place to do it. You can apply this pattern with $http, $resource, RESTangular or any other data access framework. And that's the whole point: BY ABSTRACTING THE DATA ACCESS CODE, THE CONTROLLER DOESN'T CARE HOW DATA IS FETCHED; IT ONLY EXPECTS A PROMISE TO BE RETURNED WHICH WILL LATER BE RESOLVED OR REJECTED.Let's get started!
THE OLD WAY: USE $HTTP DIRECTLY Angular provides the $http and $resource "services" for making HTTP calls to load data into your app. In tutorials and simple applications these are frequently injected directly into UI controllers: function DonutController($scope, $http) {// get the data
$http.get('/api/donut/listAll') .then(function(response) { // no fry cakes here $scope.donuts = response.data.fritters;});
}
view raw
DonutController.js
hosted with ❤ by GitHub Here the controller invokes $http directly and asks it to fetch data from a known URL. The same approach works for $resource as well. While this approach is simple, it offers limited flexiblity and begins to overcomplicate the controller when data access becomes nontrivial. Assume we have a number of UI widgets on this page that control the type of donuts we wish to load. When we invoke the backend service, we need to pass parameters to filter the donut based on size, filling, glaze and presence of a hole: function DonutController2($scope, $http) { // called from the partial on button click $scope.fetchDonuts = function() { // construct url based on values bound to form elements var url = '/api/donuts/list?size=' + $scope.size + '&filling=' + $scope.filling + '&glaze=' + $scope.glaze + '&hole=' + $scope.hasHole ? 1 : 0;// feed me
$http.get(url)
.then(function(response) { $scope.donuts = response.data.results;});
}
}
view raw
DonutController2.js
hosted with ❤ by GitHub The code to construct the URL is getting more complex and muddying up the controller a bit. Furthermore if we have other views that need to fetch these donuts this code would need to duplicated. Clearly we can improve the design through some refactoring and application ofpatterns.
THE NEW WAY: USE A REPOSITORY This technique involves adding an intermediate layer between the controller and $http that encapsulates data access and simplifies the code in the controller. Here's a simple example of this expressed asan Angular module:
var donutModule = angular.module('donuts', ); donutModule.service('donutRepository', ); donutModule.controller('donutController',);
view raw
DonutRepositoryExample.js hosted with ❤ by GitHub Note: I'm calling this intermediate a "Repository" although other terminology is likely valid, based on your preference. See "Quick Noteon Names" below.
The Repository provides a very similar API as $http in that it ultimately returns a Promise that is later resolved with the data returned by the server. However, it exposes a set of methods which provide a cleaner API to the controller than forcing it to perform string concatenation to build up URLs that are passed to $http. USING A REPOSITORY TO SWAP OUT MOCKS AND REAL SERVICES Now let's explore how we can easily swap out real and mock services with another simple Angular module example: var donutModule = angular.module('donuts', ); window.DonutRepository = function($http) {this.$http = $http;
this.fetchDonuts = function(size, filling, glaze, hasHole) { var url = '/api/donuts/list?size=' + size + '&filling=' + filling +'&glaze=' + glaze +
'&hole=' + hasHole ? 1 : 0; // invoke real service return this.$http.get(url) .then(function(response) { return response.data.results;});
};
}
window.DonutRepositoryMock = function($http) {this.$http = $http;
this.fetchDonuts = function(size, filling, glaze, hasHole) { // just get data from a flat JSON file return this.$http.get('/mockdata/donut/fetch.json') .then(function(response) { return response.data.results;});
};
}
donutModule.factory('donutRepository',);
view raw
DonutRepositoryMock.js hosted with ❤ by GitHub Now we have a new "mock" implementation that loads a JSON file from the local web server. We use Angular's factory method to control exactly what object is bound as donutRepository for injection into the controller. Alternatively the mock implementation could simply create its own data programmatically and return a promise using the $q anddeferred APIs:
var donutModule = angular.module('donuts', ); donutModule.service('donutRepository', );view raw
DonutRepositoryInMemoryMock.js hosted with ❤ by GitHub The configModel referenced by the factory above is a simple object that holds configuration information about the application. The implementation below allows us to control the config options by passing parameters via the URL to the AngularJS app on startup: var appModule = angular.module('myApp', ); appModule.service('configModel', );appModule.run()
view raw
ConfigModel.js
hosted with ❤ by GitHub Accessing the application via http://some.url/index.html#?useMocks=true will enable mock mode, basedon the code above.
Once we push all data access code into its own discrete layer we can derive other benefits as well. We can easily centralize cross-cutting concerns such as logging or caching into our repository layer. If we need to implement offline mode in an application, each repository can collaborate with a service that queues up requests and pushes them to $http once the application comes back online. This is vastly preferrable to managing this complexity in a controller.SAMPLE APPLICATION
I've built a very basic "Reddit Browser" AngularJS application that provides a working sample of these techniques. The code is available on Github here: "blog-examples" repository Clone the repo and then start the Node web server script using: ./scripts/web-server.js The app will be available here: http://localhost:8000/ng-repository/src/index.html "Mock mode" can be run easily via hitting dev.html instead. Feedback is encouraged. Drop me a comment below, use my contact form or hit me up on Twitter. A QUICK NOTE ON NAMES I pushed this section to the end because it's just dealing with semantics. I chose "Repository" as the term for the the new data access layer but there are a variety of terms that are sensible. At the end of the day, the name has significance but the application of the pattern is what really matters. Here are a few other options: * Proxy: because the intermediate sits between the client controller code and (ultimately) the backend server hosting the service. However, "Proxy" is an extremely generic pattern and doesn't really tell us what it's acting as a proxy to. * Service: due to the popularity of the Service Oriented Architecture (SOA) buzzword, components residing on a server that return data in a HTTP response are frequently called "Services." Therefore we could call the intermediate a Service. However, in the context of an AngularJS application this would be confusing since "service" is used generically to describe virtually any object available for dependency injection in the AngularJS context. * Repository: made popular in Eric Evans' book entitled Domain-Driven Design: Tackling Complexity in the Heart of Software,
a Repository can be used in server side code to encapsulate querying and persistence, ultimately returning one or more Domain Objects. This aligns pretty closely with what's going on in the AngularJS app so I decided to go with it. * Data Access Object (DAO): this one is popular in Java circles. It's probably at least as valid as Repository, perhaps moreso since it doesn't carry along the Domain Model connotations. It's up to you. Pick what you like. :) Posted in AngularJS , JavaScript.
September 9, 2013
by Cliff Meyers.
* September 9, 2013
* Cliff Meyers
* AngularJS
* JavaScript
* 10 Comments
10 Comments
7 Likes
Share
CODE ORGANIZATION IN LARGE ANGULARJS AND JAVASCRIPT APPLICATIONS Many developers struggle with how to organize an application's code base once it grows in size. I've seen this recently in AngularJS and JavaScript applications but historically it's been a problem across all technologies including many Java and Flex apps I've worked on inthe past.
The general trend is an obsession with organizing things BY TYPE. It bears a striking resemblance to the way people organize theirclothing.
PILES ON THE FLOOR
Let's take a look at angular-seed , the official starting point for AngularJS apps. The "app" directory contains the followingstructure:
* css/
* img/
* js/
* app.js
* controllers.js
* directives.js
* filters.js
* services.js
* lib/
* partials/
The JavaScript directory has one file for every type of object we write. This is much like organizing your clothes into different piles on the floor. You have a pile of socks, underwear, shirts, pants, etc. You know your black wool socks are in that pile in the corner but it's going to take a while to dig them out. This is a mess. People shouldn't live like this and developers shouldn't code like this. Once you get beyond a half-dozen or so controllers or services these files become unwieldy: objects you're looking for are hard to find, file changesets in source control becomeopaque, etc.
THE SOCK DRAWER
The next logical pass at organizing JavaScript involves creating a directory for some of the archetypes and splitting objects into their own files. To continue the clothing metaphor, we've now invested in a nice mohaghony dresser and plan to put socks in one drawer, underwear in another, and neatly fold our pants and shirts in still others. Let's imagine we're building a simple e-commerce site with a login flow, product catalog and shopping cart UI's. We've also defined new archetypes for Models (business logic and state) and Services (proxies to HTTP/JSON endpoints) rather than lumping them into Angular's single "service" archetype. Our JavaScript directory can now look like this:* controllers/
* LoginController.js * RegistrationController.js * ProductDetailController.js * SearchResultsController.js* directives.js
* filters.js
* models/
* CartModel.js
* ProductModel.js
* SearchResultsModel.js* UserModel.js
* services/
* CartService.js
* UserService.js
* ProductService.js
Nice! Objects can now be located easily by browsing the file tree or using IDE shortcuts, changesets in source control now clearly indicate what was modified, etc. This is a major improvement but still suffers from some limitations. Imagine you're at the office and realize you need a few outfits dry-cleaned for a business trip tomorrow morning. You call home and ask your significant other to take your black charcoal and blue pinstripe suits to the cleaners. And don't forget the grey shirt with the black paisley tie and the white shirt with the solid yellow tie. Imagine that your significant other is completely unfamiliar with the your dresser and wardrobe. As they sift through your tie drawer they see three yellow ties. Which one to pick? Wouldn't it be nice if your clothing was organized by outfit? While there are practical constraints like cost and space that make this difficult with clothing in the real world, something similar can be done with code at zero cost.MODULARITY
Hopefully the trite metaphors haven't been too tedious but here's therecap:
* Your significant other is the new developer on the team who's been asked to fix a bug on one of the many screens in your app. * The developer sifts through the directory structure and sees all the controllers, models and services neatly organized. Unfortunately it tells him/her nothing about which objects are related or have dependencies on one another. * If at some point the developer wants to reuse some of the code, they need to collect files from a bunch of different folders and will invariably forget code from another folder somewhere else. Believe it or not, you rarely have a need to reuse all of the controllers from the e-commerce app in the new reporting app you're building. You may however have a need to reuse some of the authentication logic. Wouldn't it be nice if that was all in one place? Let's reorganize the app based on functional areas:* cart/
* CartModel.js
* CartService.js
* common/
* directives.js
* filters.js
* product/
* search/
* SearchResultsController.js * SearchResultsModel.js * ProductDetailController.js* ProductModel.js
* ProductService.js
* user/
* LoginController.js * RegistrationController.js* UserModel.js
* UserService.js
Any random developer can now open the top-level folder and immediately gain insight into WHAT THE APPLICATION DOES. Objects in the same folder have a relationship and some will have dependencies on others. Understanding how the login and registration process work is as easy as browsing the files in that folder. Primitive reuse via copy/paste can at least be accomplished by copying the folder into anotherproject.
With AngularJS we can take this a step further and create a module ofthis related code:
var userModule = angular.module('userModule',); userModule.factory('userService', ); userModule.factory('userModel', ); userModule.controller('loginController', ); userModule.controller('registrationController', );view raw
UserModule.js
hosted with ❤ by GitHub If we then place UserModule.js into the user folder it becomes a "manifest" of the objects used in that module. This would also be a reasonable place to add some loader directives for RequireJS orBrowserify.
TIPS FOR COMMON CODE Every application has common code that is used by many modules. We just need a place for it which can be a folder named "common" or "shared" or whatever you like. In really big applications there tends to be a lot of overlap of functionality and cross-cutting concerns. This can be made manageable through a few techniques: * If your module's objects require direct access to several "common" objects, write one or more Facades for them. This can help reduce the number of collaborators for each object since having too many collaborators is typically a code smell. * If your "common" module becomes large subdivide it into submodules that address a particular functional area or concern. Ensure your application modules use only the "common" modules they need. This is a variant of the "Interface segregation principle" from SOLID. * Add utility methods onto $rootScope so they can be used by child scopes. This can help prevent having to wire the same dependency (such as "PermissionsModel") into every controller in the application. Note that this should be done sparingly to avoid cluttering up the global scope and making dependencies non-obvious. * Use events to decouple two components that don't require an explicit reference to one another. AngularJS makes this possible via the $emit, $broadcast and $on methods on the Scope object. A controller can fire an event to perform some action and then receive a notification that the action completed. QUICK NOTE ON ASSETS AND TESTS I think there's more room for flexibility with respect to organizing HTML, CSS and images. Placing them in an "assets" subfolder of the module probably strikes the best balance between encapsulating the module's asset dependencies and not cluttering things up too much. However I think a separate top-level folder for this content which contains a folder structure that mirrors the app's package structure is reasonable too. I think it works well for tests as well. Posted in OOP , AngularJS ,JavaScript .
April 22, 2013
by Cliff
Meyers.
* April 22, 2013
* Cliff Meyers
* OOP
* AngularJS
* JavaScript
* 40 Comments
40 Comments
141
Likes
Share
INTEGRATING ANGULARJS AND I18N-JS, SWITCHING LOCALES AT RUNTIME AngularJS has really nice built-in support for number, currency and date formatting. Unfortunately it lacks two significant features: * Performing string lookup / interpolation via externalized messagebundles, and
* Allowing the application to change the current locale at runtime. A colleague of mine recently recommended the i18n-js library for internationalization. i18n-js is a lightweight library (~700 lines) which implements string lookup and formatting and is a suitable replacement for Angular's localization libraries. I've written a proof-of-concept showing how the two can be integrated and made the source available at Github.
Below is an explanation of some of the key files. Some of the gists have been trimmed slightly to ease formatting on the page, so refer to Github for the full code.(function() {
'use strict';
var I18nAdapter = function I18nAdapter(locales, defaultLocale) { this.locales = this._formatLocales(locales); this.defaultLocale = this._formatLocale(defaultLocale); I18n.locale = I18n.defaultLocale = this.defaultLocale;};
/**
* Change the current locale and load the specified resource files. * @param {String} locale * @param {Array.* @return {Promise}
*/
I18nAdapter.prototype.setLocale = function(locale, urls) { var promise, promises = ,i, url;
locale = I18nAdapter.prototype._formatLocale(locale); if (!I18n.translations) { for (i = 0; i < urls.length; i++) {url = urls;
promise = this._loadBundle(locale, url); promises.push(promise);}
// when all bundles have loaded, update the locale promise = $.when.apply(this, promises); return promise.then(function() { console.log('set locale to: ' + locale); I18n.locale = locale;});
}
I18n.locale = locale; return $.Deferred().resolve().promise();};
/**
* Load a resource bundle into the specified locale* @param locale
* @param url
* @return {Promise}
*/
I18nAdapter.prototype._loadBundle = function(locale, url) {var config = {
dataType: 'json'
};
locale = this._formatLocale(locale); I18n.translations = {}; return $.ajax(url, config) .then(function(data) { _.extend(I18n.translations, data);});
};
/**
* Get translation for key. * @param {String} key * @param {Object} options* @return {String}
*/
I18nAdapter.prototype.translate = function(key, options) { return I18n.t(key, options);};
/**
* Format number.
* @param value
* @param options
* @return {String}
*/
I18nAdapter.prototype.formatNumber = function(value, options) { return I18n.toNumber(value, options);};
/**
* Format currency.
* @param value
* @param options
* @return {String}
*/
I18nAdapter.prototype.formatCurrency = function(value, options) { return I18n.toCurrency(value, options);};
/**
* Format date.
* @param date
* @param format
* @return {String}
*/
I18nAdapter.prototype.formatDate = function(date, format) { return I18n.strftime(date, format);};
/**
* Convert locale name to hyphenated / all lowercase format. * @param {String} locale* @return {String}
* @private
*/
I18nAdapter.prototype._formatLocale = function(locale) { return locale.replace("_", "-").toLowerCase();};
/**
* Convert array of locale names to hyphenated / all lowercaseformat.
* @param {Array.* @private
*/
I18nAdapter.prototype._formatLocales = function(locales) {var i;
for (i = 0; i < locales.length; i++) { locales = this._formatLocale(locales);}
return locales;
};
window.I18nAdapter = I18nAdapter;}());
view raw
I18nAdapter.js
hosted with ❤ by GitHub The above adapter wraps the core i18n-js APIs and makes it easy to load message bundles for a given locale. I wanted this functionality to stand on its own, so note that there is no dependency on AngularJS itself in this file. function initAngular() { angular.element(document).ready(function() { angular.bootstrap(document, );});
}
function initI18n() { var i18n = new I18nAdapter(, 'en_US'); i18n.setLocale('en-us', ).then(initAngular);
window.i18nAdapter = i18n;}
view raw
index.html
hosted with ❤ by GitHub The code above goes in the root HTML page and is used to load the message bundles for the default locale and then bootstrap the Angular application. This ensures all bundles are finished loading before the Angular application inits. This can be important if some application modules require the translations or formatters to be ready duringinitialization.
(function() {
'use strict';
var module = angular.module('I18nAngular', ); module.filter('translate', function() { return function(key) { return i18nAdapter.translate(key);};
});
module.filter('number', function() { return function(value) { return i18nAdapter.formatNumber(value);};
});
module.filter('currency', function() { return function(value) { return i18nAdapter.formatCurrency(value);};
});
module.filter('date', function() { return function(value, format) { return i18nAdapter.formatDate(value, format);};
});
}());
view raw
I18nAngular.js
hosted with ❤ by GitHub The above snippet exposes the i18n-js functionality via a few straightforward AngularJS filters. If other application components require access ot the I18nAdapter itself, it would be easy to add a service or factory here to make the adapter injectable. If you clone the Github repo and run it under a web server, you can see a very simple AngularJS app making use of this code. Enjoy! Posted in AngularJS , JavaScript, Localization .
March 12, 2013 by CliffMeyers.
* March 12, 2013
* Cliff Meyers
* AngularJS
* JavaScript
* Localization
* 10 Comments
10 Comments 8 LikesShare
LOCALIZATION TIPS, PART 4: LOCALIZATION RESOURCES ON THE WEB _This is the fourth and final entry in a multi-part series aboutlocalization._
Below is a collection of links to various localization resources outon the web.
GETTING STARTED
* Unicode Consortium - What is Unicode?* Glossary of Terms
DOWNLOAD UNICODE DATA Unicode Common Locale Data Repository * Download "core.zip" from the "Data" column * Uncompress and open the "common/main" folder * Open the language or locale file of your choice. There is a huge amount of data including: * Names of world languages, scripts and countries * Exemplar characters * Calendar system, date/time formats, time zone names * Number systems and names* Currencies
EXPLORE UNICODE DATA Locale Explorer - an online interface for viewing much of the data above. INTERACTIVE COLLATION TOOL Interactive Demo (Danish)-
interactive tool that allows arbitrary strings of text to be entered and sorted in various ways. Posted in Localization .February 1, 2013
by Cliff Meyers.
* February 1, 2013
* Cliff Meyers
* Localization
* 1 Comment
1 Comment
0 Likes
Share
JQUERY GLOBALIZE AND ANGULARJS INTEGRATION IN UNDER 100 LINES The other day I threw together a quick proof-of-concept for integrating AngularJS with the jQuery Globalize Plugin . The first part is a simple utility Angular "service" which loads the appropriate JSONmessage bundle:
factory('LocalizeConfig', )view raw
Localize.js
hosted with ❤ by GitHub It is bootstrapped from run() in app.js:run();
view raw
app.js
hosted with ❤ by GitHub Source code is available on Github.
Just fire up launch.html to view the sample app initializing withdifferent locales.
I'm still working on a more thorough evaluation of jQuery Globalize itself. Assuming it meets the criteria, a few more improvements cometo mind:
* Currency filter
* Date/time filter
* Switching locales at runtime Hope you found this one interesting! Posted in AngularJS , jQuery, Localization ,
JavaScript .
January 31, 2013
by Cliff
Meyers.
* January 31, 2013
* Cliff Meyers
* AngularJS
* jQuery
* Localization
* JavaScript
* 1 Comment
1 Comment
5 Likes
Share
Older
CLIFF MEYERS
All about software development: HTML5, JavaScript, Angular, React, Java, Android. And other things.* Blog
* About
* Contact
Software engineer at Capital One working on the flagship web application used by millions of customers every day.* AngularJS
* AOP
* Books
* Eclipse
* Flash
* Flex
* Git
* Hibernate
* HTML5
* Java
* JavaScript
* jQuery
* Localization
* Mac
* Mustache
* OOP
* Sencha Touch
* Spring
* Subversion
* Testing
* Tools
ON THE TWITTER
*
RT @dtrinh : Last I'll speak on it — I was SIM swapped and even if you have a passcode on your SIM, it's likely you can be too.… https://t.co/V0azzJK9i7 A month ago*
If you're a @Chase customer you might want to send them this letter to reject mandatory arbitration and preserve yo… https://t.co/ZPbHBzt2FP A month ago*
RT @ET_Exists : Actor James Doohan, who played the beloved Scotty in Star Trek, served in the 3rd Canadian Infantry Division respon… https://t.co/SjeMtvbHM1 2 months agogithub
Details
Copyright © 2024 ArchiveBay.com. All rights reserved. Terms of Use | Privacy Policy | DMCA | 2021 | Feedback | Advertising | RSS 2.0