tips for angular applications

30
© Copyright SELA software & Education Labs Ltd. | 14-18 Baruch Hirsch St Bnei Brak, 51202 Israel | www.selagroup.com SELA DEVELOPER PRACTICE MAY 31, 2015 – JUNE 4, 2015 Sebastian Pederiva Tips for Angular Applications Senior Consultant [email protected] @spederiva tiny.cc/SebastianBlog

Upload: sebastian-pederiva

Post on 28-Jul-2015

148 views

Category:

Internet


2 download

TRANSCRIPT

© Copyright SELA software & Education Labs Ltd. | 14-18 Baruch Hirsch St Bnei Brak, 51202 Israel | www.selagroup.com

SELA DEVELOPER PRACTICEMAY 31, 2015 – JUNE 4, 2015

Sebastian Pederiva

Tips for Angular Applications

Senior Consultant

[email protected]

@spederiva

tiny.cc/SebastianBlog

Starting

Project Structure

Roll your own Angular Seed https://github.com/angular/angular- seed

Project Structure…by components

Add Suffix to the file names

Easy to read and understandEssential for “component type” structureHelp make better automation and testing

product-list.ctrl.jsproduct-list.tpl.htmlproduct-list.fltr.jsproduct-list.fctry.jsproduct-list.srv.jsproduct-list.const.jsproduct-list.val.js

Separate to Modules

var corelist = app.module("app.core.list", []);

corelist.controller("app.core.list.listCtrl", ...)

angular.module(“app.common.services")

.service("myApp.common.services.product"

Golden RulesControllers should never refer to any DOM elementsControllers should call services vs. holding too much business logicAvoid $rootScope, try to use services insteadExpression {{}} vs ng-cloak

Minimizing Angular Files

Minimizing process will replace variable names compromising the dependency injection

someModule.controller('MyController', ['$scope', function($scope) { $scope.name = "Sebastian";

}]);

someModule.controller('MyController', function ($scope) {$scope.name = "Sebastian";

});

someModule.controller('MyController', function (a) {a.name = "Sebastian";

});

One Time Binding

Use double colon ::https://code.angularjs.org/1.3.15/docs/guide/expression#one-time-bindingFor previous versions: https://github.com/Pasvaz/bindonce

<p id="one-time-binding-example">One time binding: {{::name}}

</p>

Controller Inheritanceapp.controller("ChildCtrl", ["$scope", function ($scope) {

$scope.childText = "childText" $scope.text = "childText”

}]);

app.controller("ParentCtrl", ["$scope", function ($scope) { $scope.parentText = "parentText" $scope.text = "parentText”

}]);

<div ng-controller="ParentCtrl”> <div ng-controller="ChildCtrl”> {{parentText}} <br/> {{childText}} <br/> {{text}} </div>

</div>

Controller Inheritanceapp.controller("ChildCtrl", function ($scope, $controller) {

$controller("ParentCtrl", {$scope: $scope});

$scope.childText = "childText";$scope.text = "childText";

});

app.controller("ParentCtrl", ["$scope", function ($scope) { $scope.parentText = "parentText" $scope.text = "parentText”

}]);

<div ng-controller="ChildCtrl”> {{parentText}} <br/> {{childText}} <br/> {{text}}

</div>

Avoid Watchers$watch occurs when the users clicks on an item, not when the model changesConsider using events insteadMinimize use watchersAngular uses dirty checking to keep track of all the changes in app

ng-repeat, track when possiblengRepeat does not allow duplicate items in arraysTrack by to increase performanceDefault tracking<div ng-repeat=”item in collection track by $id(obj)”>

Own tracking<div ng-repeat=”item in collection track by item.id”>

https://docs.angularjs.org/api/ng/directive/ngRepeat#tracking-and-duplicates

ng-repeat

How many times will getPrice function be called? Use watch collection to calculate everything when the controller is first invoked

<tr ng-repeat="item in items"><td>{{item.name}}</td><td>{{item.description}}</td><td>{{getPrice(item.id)}}</td>

</tr>

ng-repeat cont

<tr ng-repeat="item in items"><td>{{item.name}}</td><td>{{item.description}}</td><td>{{item.price}}</td>

</tr>

$scope.$watchCollection('items', function (newItems) {for (var i = 0; i < newItems.length; i++) { newItems[i].price = getPrice(newItems.id);

}$scope.items = newItems;

});

Debounce ng-model

Lot of updates?

https://docs.angularjs.org/api/ng/directive/ngModelOptions <input ng-model="name”ng-model-options="{ debounce: 500 }” />

Use ng-if instead of ng-showng-show will render an element, and use display:none to hide itng-if will actually removes the element from DOM, and will re-create it, if it’s needed.

Promise you use Promises

Prefer Promises Over CallbacksFollow The ‘...ing’ ConventionClear Indication You’re getting a Promise

function gettingUsers(){return $http()...

}

gettingUsers().success().error()

Destroying Memory Leaks

Use $scope.$on('$destroy', …)Remove handlersClean up resources which won’t be garbage collected automatically

module.controller("TestController", function ($scope, $timeout) {

var onTimeout = function () {$scope.value += 1;timer = $timeout(onTimeout, 1000);

};var timer = $timeout(onTimeout, 1000);

$scope.value = 0;

$scope.$on("$destroy", function () {if (timer) {$timeout.cancel(timer);}

});});

Managing the Time…use moment.js

https://github.com/urish/angular-moment

<span am-time-ago="message.time"></span>

Use Batarang

DebuggingPause On Caught Exceptions

DebuggingAttach DOM Breakpoints

LoggingAvoid using console.log in your controllers Use $log instead$log can be extended to provide additional logging capabilities

Forget jQuery ExistsjQuery-- Use angular.element instead of $() selector -- Search for a jQuery-equivalent instead »  Examples-- html(), text(), val() »  Ask whether you can use directives instead Take a look at ui-bootstrap’s directives at https://github.com/angular-ui/bootstrap/tree/master/src

Testing

Faster Bug TrackingJasmine Givenhttp://www.airpair.com/angularjs/workshops/unit-testing-angularjs

describe("assigning stuff to this", function() { Given(function() { this.number = 24; }); Given(function() { this.number++; }); When(function() { this.number *= 2; }); Then(function() { expect(this.number).toBe(50) });});

Questions