Евгений Жарков AngularJS: Good parts
-
Upload
fwdays -
Category
Technology
-
view
669 -
download
1
Transcript of Евгений Жарков AngularJS: Good parts
![Page 2: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/2.jpg)
Watchers ]:>
![Page 3: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/3.jpg)
Track Watchers
Angular adds a watcher to the digest cycle for each of these:• {{expression}} — templates• $scope.$watch — in the code
![Page 4: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/4.jpg)
Track WatchersfunctiongetWatchers(root){root=angular.element(root||document.documentElement);varwatcherCount=0;functiongetElemWatchers(element){varisolateWatchers=getWatchersFromScope(element.data().$isolateScope);varscopeWatchers=getWatchersFromScope(element.data().$scope);varwatchers=scopeWatchers.concat(isolateWatchers);angular.forEach(element.children(),function(childElement){watchers=watchers.concat(getElemWatchers(angular.element(childElement)));});returnwatchers;}functiongetWatchersFromScope(scope){if(scope){returnscope.$$watchers||[];}else{return[];}}returngetElemWatchers(root);}
https://gist.github.com/kentcdodds/31c90402750572107922
![Page 5: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/5.jpg)
Track Watchers
//getallwatchersonthewholepagegetWatchers();//getwatchersofaspecificelement(anditschildren)getWatchers(document.body);//selecttheelementofinterestinChromeDevtoolsgetWatchers($0);
![Page 6: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/6.jpg)
![Page 7: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/7.jpg)
Track Watchers
![Page 8: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/8.jpg)
![Page 9: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/9.jpg)
![Page 10: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/10.jpg)
![Page 11: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/11.jpg)
https://github.com/kentcdodds/ng-stats
![Page 12: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/12.jpg)
AngularJS > ES6
![Page 13: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/13.jpg)
ES6, require.js
functionMainController(){……………}
export{MainController}
—————————————————————————————————————
import{MainController}from‘./path/to/MainController';……………
![Page 14: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/14.jpg)
ES6, require.jsclassMainController{
constructor(searchService){this.searchService=searchService;}
search(){this.searchService.fetch(this.searchTerm).then(response=>{this.items=response.data.items;});}}
export{MainController}
![Page 15: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/15.jpg)
ES6, require.js
import{MainController}from'./MainController';
import{SearchService}from'./SearchService';
angular
.module('app',[])
.controller('mainController',MainController)
.service('searchService',SearchService);
![Page 16: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/16.jpg)
Inheritance
classPageController{
constructor(title){
this._title=title;}
title(){
return'Title:'+this._title;}}
export{PageController}
![Page 17: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/17.jpg)
Inheritance
import{PageController}from'./PageController';
classProductPageControllerextendsPageController{
constructor(){
super('ES6inheritancewithAngular’);
}}
export{ProductPageController}
![Page 18: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/18.jpg)
Inheritance
import{ProductPageController}from'./ProductPageController';
angular
.module('app',[])
.controller('ProductPageController',ProductPageController);
![Page 19: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/19.jpg)
Service Inheritance
myModule.service(fn)
YES, instantiated with the new operator under the hood
myModule.factory(fn)
NO
![Page 20: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/20.jpg)
Don’t forget about minification
MainController.$inject=['SearchService'];
![Page 21: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/21.jpg)
and/or ng-annotate
exportdefaultclassNameService{
/*@ngInject*/
constructor($q){..}
}
![Page 22: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/22.jpg)
ES6 Babel Browserify Boilerplate
https://github.com/thoughtram/es6-babel-browserify-boilerplate
![Page 23: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/23.jpg)
Angular ES6
https://github.com/michaelbromley/angular-es6
![Page 24: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/24.jpg)
AngularJS > ES6 > Tests
![Page 25: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/25.jpg)
ES5, Karma, Jasmine, PhantomJSdescribe('TodoService',function(){
varTodoService,InitialTodosMock;//InstantiateAngularJScontextbeforeEach(module("app"));//RegistermocksinAngularJScontextbeforeEach(module(function($provide){InitialTodosMock=[{label:'Testtodo',done:false}];$provide.value('initialTodos',InitialTodosMock);}));//GetinstanceofTodoServicewithmockeddependenciesfromAngularJScontextbeforeEach(inject(function(_TodoService_){TodoService=_TodoService_;}));//Oh,...dotheactualtesting!!!it('shouldhaveinitialtodo',function(){expect(TodoService.todos.length).toBe(1);expect(TodoService.todos[0].label]).toBe('Testtodo');expect(TodoService.todos[0].done]).toBe(false);
});});
![Page 26: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/26.jpg)
ES5, Karma, Jasmine, PhantomJSdescribe('TodoController',function(){varscope,$rootScope,$controller;//InstantiateAngularJScontextbeforeEach(module('app'));//RegistermocksinAngularJScontext//(sometimesnotnecessary,wecanuserealservicestoo,buttheAngularcontextgrows...)beforeEach(module(function($provide){varTodoServiceMock={todos:[],addTodo:function(){/*……*/},toggleTodo:function(){/*……*/},removeDoneTodost(){/*……*/}};$provide.value('TodoService',TodoServiceMock);}));//GetinstanceofTodoController,youknow,createnew$scopefrom$rootScopebyyourselfandstuff...//Itispossibletonotuse$scopewhenusing'controllerAs'syntax,//butyoustillhavetouseatleast$controllertogettherefferencetocontrolleritselfbeforeEach(inject(function(_$rootScope_,_$controller_,_TodoService_){$controller=_$controller_;$rootScope=_$rootScope_;scope=$rootScope.$new();
$controller('TodoController',{$scope:scopeTodoService:_TodoService_});}));//Oh,...dotheactualtesting!!!it('shouldhaveinitialtodos',function(){expect(scope.todos.length).toBe(1);});});
![Page 27: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/27.jpg)
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 “!”)
![Page 28: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/28.jpg)
ES6, Mocha, chaiimport{assert}from'chai';importTodoServicefrom'./todo.service.js';
letservice;
describe('TodoService',function(){beforeEach(function(){service=TodoService();});
it('shouldcontainemptytodosafterinitialization',function(){assert.equal(service.todos.length,0);});
it('shouldtoggletodo',function(){service.addTodo('Finishexampleproject');assert.equal(service.todos[0].done,false);service.toggleTodo('Finishexampleproject');assert.equal(service.todos[0].done,true);service.toggleTodo('Finishexampleproject');assert.equal(service.todos[0].done,false);});});
![Page 29: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/29.jpg)
ES6, Mocha, chaiimport{assert}from'chai';importSomeComponentfrom‘./some-component';
letcomponent;
describe('some-component',function(){beforeEach(function(){component=newSomeComponent();});
it('shouldstartwithcountervalue20',function(){assert.equal(component.counter,20);});
it('shouldacceptinitialcountervalueasdependency',function(){component=newSomeComponent(30);assert.equal(component.counter,30);});
it('shouldincrementcountervalueafterincrementiscalled',function(){assert.equal(component.counter,20);component.increment();assert.equal(component.counter,21);});});
Dependencies are passed explicitly as a parameter of function
![Page 30: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/30.jpg)
Dig, read, criticise
• Paginationhttps://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination
• angular-formly http://angular-formly.com/
• angular-translatehttps://angular-translate.github.io
• LumX (material design) http://ui.lumapps.com
![Page 31: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/31.jpg)
angular-formly
<formly-formmodel="vm.user"fields="vm.userFields">
<buttontype="submit"class="btnbtn-default"ng-click="vm.submit(vm.user)">Submit</button>
</formly-form>
![Page 32: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/32.jpg)
angular-formlyvm.userFields=[{key:'email',type:'input',templateOptions:{type:'email',label:'Emailaddress',placeholder:'Enteremail'}},{key:'password',type:'input',templateOptions:{type:'password',label:'Password',placeholder:'Password'}},
{key:'file',type:'file',templateOptions:{label:'Fileinput',description:'Exampleblock-levelhelptexthere',url:'https://example.com/upload'}},{key:'checked',type:'checkbox',templateOptions:{label:'Checkmeout'}}];
![Page 33: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/33.jpg)
Pagination
<ANY
dir-paginate="expression|itemsPerPage:(int|expression)[:paginationId(stringliteral)]"
[current-page=""]
[pagination-id=""]
[total-items=""]>
...
</ANY>
![Page 34: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/34.jpg)
Pagination
<dir-pagination-controls
[max-size=""]
[direction-links=""]
[boundary-links=""]
[on-page-change=""]
[pagination-id=""]
[template-url=""]
[auto-hide=""]>
</dir-pagination-controls>
![Page 35: Евгений Жарков AngularJS: Good parts](https://reader033.fdocuments.net/reader033/viewer/2022051706/58ef21091a28abb45a8b45d7/html5/thumbnails/35.jpg)