📜 ⬆️ ⬇️

Create Awesome Apps on AngularJS

Documentation on Angulyar is great for getting started and picking at the API. However, it does not explain how to organize and manage an application when it grows to tens or hundreds of thousands of lines of code. I have gathered here some of my observations and best practices for managing sprawling applications. First, take a look at the organization, then move on to some tips for improving performance and end with a brief summary of the tools, servers, and build process. This post will focus on large applications, in particular, there is an excellent article on the best practices of AngularJS from the December meeting, which is also worth a look.

Do not write huge applications


The best advice on huge apps is not to do them. Write small, focused, modular pieces and gradually merge them into larger pieces to build the application. (This advice was given by the hacker node.js, cool in all respects, dude @substack ).

Organization


Probably the biggest question for large applications is where to put all the code. Files, directories, modules, services, and controllers fall into a set of things that require organization. For a quick overview of a good project structure, see the AngularJS template project on Github . Nevertheless, I would like to dig deeper and offer some additional recommendations on the project structure. Let's start with the directories and move down the list.
')
Catalogs

Typical recommended folder structure:

 root-app-folder
 Index── index.html
 Scrip── scripts
 │ ├── controllers
 │ │ └── main.js
 │ │ └── ...
 │ ├── directives
 │ │ └── myDirective.js
 │ │ └── ...
 │ ├─ filters
 │ │ └── myFilter.js
 │ │ └── ...
 │ ├── services
 │ │ └── myService.js
 │ │ └── ...
 │ ├── vendor
 │ │ ├── angular.js
 │ │ ├── angular.min.js
 │ │ ├── es5-shim.min.js
 │ │ └── json3.min.js
 │ └── app.js
 ├── styles
 │ └── ...
 Views── views
     Main── main.html
     └── ...

As new files are added, it may make sense to create subdirectories for the further organization of controllers and services. For example, I often find myself catching up with the models directory inside services . As a rule, I also sort files by directories, if there is some rational hierarchy with which you can organize file storage.

On the topic of organization of code, read the same way Organization of code in large AngularJS and JavaScript applications (approx. Translator)

Files

Each file must contain one “entity”, where the “entity” is a controller, directive, filter, or service. This allows, at a minimum, to focus files. It also helps create a litmus test for API testing. If you find yourself flipping files back and forth too often, this is a sign that your APIs are too complex. It is necessary to rethink, reorganize and simplify them.

I would like to make an exception for closely related directives. For example, if there is a directive , , .


app.js :

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js :

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js :

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
 ,     ,       . 


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
 ,     ,       . 


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
 ,     ,       . 


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
 ,     ,       . 


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
 ,     ,       . 


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
 ,     ,       . 


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
 ,     ,       . 


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
 ,     ,       . 


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
 ,     ,       . 


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .
, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

, , .


app.js
:

angular.module('yourAppName', ['yourAppDep']); angular.module('yourAppDep');
, .. :

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
( ) , . Google+ . , , , , .

, , , . , , . , /. , , , , .


, , , .., . , . .

API- . .


. . , ngmodules , .

, «The Best Todo List App Ever», «btla».

angular.module('yourAppDep').directive('btlaControlPanel', function () { // ... });
, , , . GZIP- - .


angular.module('yourAppDep').service('MyCtrl', function () { // ... });

- , . , , , . , .

NoSQL , CouchDB MongoDB, JavaScript- (POJO) . , MySQL, - , . RESTful-, $resource . , , . , . .

, Underscore.js , , Backbone.js.


, "Ctrl".

angular.module('yourAppDep').controller('MyCtrl', function () { // ... });
, . , . , , , , . .


, , . , , . . -, . Batarang .

(digest)
«». StackOverflow .

. , -, , . , 30 .

app.factory('socket', function ($rootScope) { var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, function () { // var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } // ... }; });
, «» , . Underscore.js , , socket :

app.factory('socket', function ($rootScope) { // Underscore.js 1.4.3 // http://underscorejs.org // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license. // _.throttle // https://github.com/documentcloud/underscore/blob/master/underscore.js#L626 // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. var throttle = function (func, wait) { var context, args, timeout, result; var previous = 0; var later = function() { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function() { var now = new Date(); var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); } else if (!timeout) { timeout = setTimeout(later, remaining); } return result; }; }; var socket = io.connect(); return { on: function (eventName, callback) { socket.on(eventName, throttle(function () { // 500 var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }, 500)); } // ... }; });
, . $scope.$digest $scope.$apply . $digest , .

, , $scope.$watch . , . , , .


, , . , , .

, , , . , $filter .

, , , :

{{someModel.name | titlecase}}
.

angular.module('myApp').controller('MyCtrl', function ($scope, $http, $filter) { $http.get('/someModel') .success(function (data) { $scope.someModel = data; // «titlecase» $scope.someModel.name = $filter('titlecase')($scope.someModel.name); }); });
, , . JavaScript , . , Underscore.js , . , . . , , .

, (. )


. , . , (E2E) . , — , . , , . .

, . , , . . , .


Yeoman , , . .

Batarang , .


, , . . Node.js Nginx . Nginx , Node.js RESTful API / . Node.js . , -, .

, Nodejitsu Linode . Nodejitsu , Node.js. , . Node.js, . , Linode . Linode API . , .

, .


, , , , 2013 . ngmin , , , , , AngularJS .

, , - app.js , ngmin , , , Closure Compiler --compilation_level SIMPLE_OPTIMIZATIONS . angular.js .

RequireJS . , , , , RequireJS .


- . , . , , .

-? , , - .

Source: https://habr.com/ru/post/182556/


All Articles