Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

0

Share

Download to read offline

Евгений Жарков AngularJS: Good parts

Download to read offline

Став популярным Angular активно обтачивался и дорабатывался активистами, приложения написанные 2-3 года назад и сейчас имеют отличия, мы посмотрим какие.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

Евгений Жарков AngularJS: Good parts

  1. 1. AngularJS: Good parts Евгений Жарков DOOR3 @2j2e eu.zharkov@gmail.com
  2. 2. Watchers ]:>
  3. 3. Track Watchers Angular adds a watcher to the digest cycle for each of these: • {{expression}} — templates • $scope.$watch — in the code
  4. 4. Track Watchers function getWatchers(root) { root = angular.element(root || document.documentElement); var watcherCount = 0; function getElemWatchers(element) { var isolateWatchers = getWatchersFromScope(element.data().$isolateScope); var scopeWatchers = getWatchersFromScope(element.data().$scope); var watchers = scopeWatchers.concat(isolateWatchers); angular.forEach(element.children(), function (childElement) { watchers = watchers.concat(getElemWatchers(angular.element(childElement))); }); return watchers; } function getWatchersFromScope(scope) { if (scope) { return scope.$$watchers || []; } else { return []; } } return getElemWatchers(root); } https://gist.github.com/kentcdodds/31c90402750572107922
  5. 5. Track Watchers // get all watchers on the whole page getWatchers(); // get watchers of a specific element (and its children) getWatchers(document.body); // select the element of interest in Chrome Dev tools getWatchers($0);
  6. 6. Track Watchers
  7. 7. https://github.com/kentcdodds/ng-stats
  8. 8. AngularJS > ES6
  9. 9. ES6, require.js function MainController () { …………… } export { MainController } ————————————————————————————————————— import { MainController } from ‘./path/to/MainController'; ……………
  10. 10. ES6, require.js class MainController { constructor(searchService) { this.searchService = searchService; } search () { this.searchService .fetch(this.searchTerm) .then(response => { this.items = response.data.items; }); } } export { MainController }
  11. 11. ES6, require.js import { MainController } from './MainController'; import { SearchService } from './SearchService'; angular .module('app', []) .controller('mainController', MainController) .service('searchService', SearchService);
  12. 12. Inheritance class PageController { constructor(title) { this._title = title; } title () { return 'Title: ' + this._title; } } export { PageController }
  13. 13. Inheritance import { PageController } from './PageController'; class ProductPageController extends PageController { constructor() { super('ES6 inheritance with Angular’); } } export { ProductPageController }
  14. 14. Inheritance import { ProductPageController } from './ProductPageController'; angular .module('app', []) .controller('ProductPageController', ProductPageController);
  15. 15. Service Inheritance myModule.service(fn) YES, instantiated with the new operator under the hood myModule.factory(fn) NO
  16. 16. Don’t forget about minification MainController.$inject = ['SearchService'];
  17. 17. and/or ng-annotate export default class NameService { /*@ngInject*/ constructor($q) { .. } }
  18. 18. ES6 Babel Browserify Boilerplate https://github.com/thoughtram/es6-babel-browserify-boilerplate
  19. 19. Angular ES6 https://github.com/michaelbromley/angular-es6
  20. 20. AngularJS > ES6 > Tests
  21. 21. ES5, Karma, Jasmine, PhantomJS describe('TodoService', function() { var TodoService, InitialTodosMock; // Instantiate Angular JS context beforeEach(module("app")); // Register mocks in Angular JS context beforeEach(module(function($provide) { InitialTodosMock = [ { label: 'Test todo', done: false } ]; $provide.value('initialTodos', InitialTodosMock); })); // Get instance of TodoService with mocked dependencies from Angular JS context beforeEach(inject(function (_TodoService_) { TodoService = _TodoService_; })); // Oh, ... do the actual testing !!! it('should have initial todo', function() { expect(TodoService.todos.length).toBe(1); expect(TodoService.todos[0].label]).toBe('Test todo'); expect(TodoService.todos[0].done]).toBe(false); }); });
  22. 22. ES5, Karma, Jasmine, PhantomJS describe('TodoController', function() { var scope, $rootScope, $controller; // Instantiate Angular JS context beforeEach(module('app')); // Register mocks in Angular JS context // (sometimes not necessary, we can use real services too, but the Angular context grows...) beforeEach(module(function($provide) { var TodoServiceMock = { todos: [], addTodo: function() { /*……*/ }, toggleTodo: function() { /*……*/ }, removeDoneTodost() { /*……*/ } }; $provide.value('TodoService', TodoServiceMock); })); // Get instance of TodoController, you know, create new $scope from $rootScope by yourself and stuff... // It is possible to not use $scope when using 'controllerAs' syntax, // but you still have to use at least $controller to get the refference to controller itself beforeEach(inject(function(_$rootScope_, _$controller_, _TodoService_){ $controller = _$controller_; $rootScope = _$rootScope_; scope = $rootScope.$new(); $controller('TodoController', { $scope: scope TodoService: _TodoService_ }); })); // Oh, ... do the actual testing !!! it('should have initial todos', function() { expect(scope.todos.length).toBe(1); }); });
  23. 23. Issues • Angular context module(‘app’) must be instantiated to be able to do any testing. Without Angular context you can’t get access (reference) to your controllers / services. • Angular and all other used libraries must be included during testing so that it is even possible to instantiate Angular context. • Angular context can grow quite large so that it’s creation will consume considerable amount of time for every test file.
 • Karma exclusion syntax doesn’t follow standard node glob pattern which can make you go crazy when you try to solve timeout errors caused by insufficient memory on PhantomJS by splitting test execution into multiple batches, while supporting dev mode single test execution (karma uses extra exclude property instead of supporting standard “!”)
  24. 24. ES6, Mocha, chai import { assert } from 'chai'; import TodoService from './todo.service.js'; let service; describe('TodoService', function() { beforeEach(function() { service = TodoService(); }); it('should contain empty todos after initialization', function () { assert.equal(service.todos.length, 0); }); it('should toggle todo', function () { service.addTodo('Finish example project'); assert.equal(service.todos[0].done, false); service.toggleTodo('Finish example project'); assert.equal(service.todos[0].done, true); service.toggleTodo('Finish example project'); assert.equal(service.todos[0].done, false); }); });
  25. 25. ES6, Mocha, chai import { assert } from 'chai'; import SomeComponent from ‘./some-component'; let component; describe('some-component', function() { beforeEach(function() { component = new SomeComponent(); }); it('should start with counter value 20', function () { assert.equal(component.counter, 20); }); it('should accept initial counter value as dependency', function () { component = new SomeComponent(30); assert.equal(component.counter, 30); }); it('should increment counter value after increment is called', function () { assert.equal(component.counter, 20); component.increment(); assert.equal(component.counter, 21); }); }); Dependencies are passed explicitly as a parameter of function
  26. 26. Dig, read, criticise • Pagination
 https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination • angular-formly 
 http://angular-formly.com/ • angular-translate
 https://angular-translate.github.io • LumX (material design) 
 http://ui.lumapps.com

  27. 27. angular-formly <formly-form model="vm.user" fields="vm.userFields"> <button type="submit" class="btn btn-default" ng-click="vm.submit(vm.user)">Submit</button> </formly-form>
  28. 28. angular-formly vm.userFields = [ { key: 'email', type: 'input', templateOptions: { type: 'email', label: 'Email address', placeholder: 'Enter email' } }, { key: 'password', type: 'input', templateOptions: { type: 'password', label: 'Password', placeholder: 'Password' } }, { key: 'file', type: 'file', templateOptions: { label: 'File input', description: 'Example block- level help text here', url: 'https://example.com/ upload' } }, { key: 'checked', type: 'checkbox', templateOptions: { label: 'Check me out' } } ];
  29. 29. Pagination <ANY dir-paginate="expression | itemsPerPage: (int| expression) [: paginationId (string literal)]" [current-page=""] [pagination-id=""] [total-items=""]> ... </ANY>
  30. 30. Pagination <dir-pagination-controls [max-size=""] [direction-links=""] [boundary-links=""] [on-page-change=""] [pagination-id=""] [template-url=""] [auto-hide=""]> </dir-pagination-controls>

Став популярным Angular активно обтачивался и дорабатывался активистами, приложения написанные 2-3 года назад и сейчас имеют отличия, мы посмотрим какие.

Views

Total views

790

On Slideshare

0

From embeds

0

Number of embeds

277

Actions

Downloads

4

Shares

0

Comments

0

Likes

0

×