└── README.md
/README.md:
--------------------------------------------------------------------------------
1 | ## Tips & Tricks
2 |
3 | #### 1. Running a code when you aren't sure whether it will be called from within angular context or outside it.
4 |
5 | ```javascript
6 | $scope.evalAsync(function () {
7 | // Your code here.
8 | });
9 | ```
10 |
11 | Note: In case you are sure you are out of angular context, its better to call `$scope.$digest` after your code instead of using `$scope.$apply` because `$apply` will call `$digest` on `$rootScope` which is much heavier.
12 |
13 | #### 2. Check if a form is dirty or invalid from your controller.
14 |
15 | ```javascript
16 | // `formName` is value of name attribute of the form.
17 | // If form is dirty.
18 | if ($scope.formName.$dirty) {
19 | }
20 |
21 | // If form is invalid.
22 | if ($scope.formName.$invalid) {
23 | }
24 | ```
25 |
26 | Note: The name attribute value of the form cannot be hyphenated as that becomes a JS variable.
27 |
28 | #### 3. Watching for changes in `name` of any user in a list of users:
29 |
30 | ```javascript
31 | $scope.watchCollection(
32 | function watchFn() {
33 | return $scope.users.map(function (user) {
34 | return user.name;
35 | });
36 | }),
37 | function watchListener() {
38 | // Fired when name of any user changes.
39 | }
40 | });
41 | ```
42 |
43 |
44 | #### 4. Make a particular HTML section compile only after some asynchronous data is fetched:
45 |
46 | In Controller:
47 | ```javascript
48 | $http.get('data_endpoint').then(function () {
49 | $scope.isDataFetched = true;
50 | })
51 | ```
52 |
53 | In HTML:
54 | ```html
55 |
56 |
57 |
58 | ```
59 |
60 |
61 | #### 5. Angular `copy` function copies the prototype properties of an object on the new object. BEWARE: If you watch such an object, you will probably get stuck in an infinite loop because `$digest` will always find the old and new objects different due to the abnormal behavior of `angular.copy`.
62 |
63 | ```javascript
64 | var obj = {a: 1};
65 | var obj1 = Object.create(obj);
66 |
67 | obj1.hasOwnProperty('a'); // Returns false
68 |
69 | var newCopy = angular.copy(obj1);
70 | newCopy.hasOwnProperty('a'); // Returns true. Property `a` is own the object itself now.
71 |
72 | ```
73 |
74 |
75 | ## Performance:
76 |
77 | #### 1. Use track by in ng-repeat expression to avoid re-rendering of compelete list:
78 |
79 | ```html
80 |
81 |
82 |
83 |
84 |
85 |
86 | ```
87 |
88 | #### 2. Debounce the change in model to prevent watchers from firing too frequently (Angular 1.3):
89 |
90 | ```html
91 |
94 | ```
95 | This will change model value only after staying idle for 300ms after the last change happened in input value.
96 |
97 |
98 | #### 3. If your page has too many watchers being used to display content which doesn't change with time, use [bindonce](https://github.com/Pasvaz/bindonce)
99 | .
100 |
101 | Adds one watcher for `user.name`:
102 |
103 | ```
104 | Welcome to the app, {{user.name}}
105 | ```
106 |
107 | Using bindonce, no watcher remains once `user.name` is available:
108 |
109 | ```html
110 | Welcome to the app,
111 | ```
112 |
113 | Note: Angular 1.3 has a similar feature:
114 |
115 | #### 4. If you have a directive that is inside an ng-repeat, its `compile` function is called only once throughout the ng-repeat. So place your common code for directives in compile function so that it executes only once per ng-repeat loop.
116 |
117 |
118 | #### 5. Watching for an item change in a list:
119 |
120 | Bad - Watch with deep comparison creates copies of objects:
121 | ```javascript
122 | $scope.watch('yourList',
123 | function watchListener() {
124 | // Fired when name of any user changes.
125 | }
126 | }, true);
127 | ```
128 |
129 | Good:
130 | ```javascript
131 | $scope.watchCollection('yourList',
132 | function watchListener() {
133 | // Fired when name of any user changes.
134 | }
135 | });
136 | ```
137 |
138 | #### 6. Avoid using filters on large arrays. Filters run on each digest loop and creates new array everytime it runs. In such cases its better to manually watch your list and do filtering when a change is detected.
139 |
140 | Bad - Filter runs on each digest loop.
141 |
142 | ```html
143 |
144 | ```
145 |
146 | Good:
147 |
148 | In Controller:
149 | ```javascript
150 | $scope.filteredItems = $scope.items;
151 | $scope.$watchCollection('items', function () {
152 | // Apply filter on change detection
153 | $scope.filteredItems = myComplexFilter($scope.items);
154 | });
155 | ```
156 |
157 | In HTML:
158 | ```html
159 |
160 | ```
161 |
162 | ## Debugging:
163 |
164 | #### 1. Many a times you want to know when an object's particular property gets set. Here is a neat trick to do it:
165 |
166 | ```javascript
167 | var obj = {a: 2};
168 |
169 | var _a = obj.a;
170 |
171 | Object.defineProperty(a, 'a', {
172 | get: function () { return _a; },
173 | set: function (val) { _a = val; console.log('prop changed'); }
174 | });
175 |
176 | // You'll get a console log whenever the property changes.
177 | ```
178 |
179 | ### Contributing
180 | - - -
181 |
182 | If you have some Angular tips and tricks you would like to get added here, please open pull request for the same.
183 |
184 |
185 | ### Credits
186 | - - -
187 |
188 | The awesome front-end folks at 
189 |
--------------------------------------------------------------------------------