Skip to content

Commit 53ff9c1

Browse files
committed
es6 components
1 parent db78763 commit 53ff9c1

File tree

9 files changed

+118
-46
lines changed

9 files changed

+118
-46
lines changed

README.md

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -895,8 +895,8 @@ I admit I was stumbling on my way to nowhere for a while, desperately searching
895895
>
896896
> <em>(Jonnie Hallman)</em>
897897
898-
Really intriguing! The solution is cripty dug there (in clear). Read that, and read it again; lucubrate, my little brain; use the Rosetta Stone to decipher Angular's documentation for [PROVIDERS][20].
899-
The keys here are factory and service providers.
898+
Really intriguing! The solution is cripty dug there (in clear). Read that, and read it again; lucubrate, my little brain; use the Rosetta Stone to decipher Angular's documentation for [providers][20].
899+
The keys here are factory and service recipes.
900900

901901
> JavaScript developers often use custom types to write object-oriented code.
902902
@@ -967,7 +967,7 @@ controller: ['searchService', 'VuexStore', function (searchService, VuexStore) {
967967
> }
968968
>```
969969
970-
Sort of simulating a Vue's computed property.
970+
The `resultsCount`function to me is like simulating a Vue's computed property.
971971
But, if you rebuild, launch the application, and start a search... WTF? No count!
972972
973973
![vuex-in-angular-component][21]
@@ -996,7 +996,7 @@ export default function (fn) {
996996
997997
I am wrapping the function in a "safe apply" to avoid possible "$apply already in progress" errors.
998998
But how to use it? One of many possible solutions follows.
999-
If you rewrite your component as an ES6 class you can simply import and use it as a module. Here we are still dealing with a classic component, so I a service as a proxy to expose it:
999+
If you rewrite your component as an ES6 class you can simply import and use it as a module. Here we are still dealing with a classic component, so I will write a service as a proxy to expose it:
10001000

10011001
**ngVueBridgeCode/services/utilities.js**
10021002
```javascript
@@ -1096,7 +1096,7 @@ export default new Vuex.Store({
10961096
});
10971097
```
10981098

1099-
If you test this code now you can easily see that, when you press the button, nothing happens. Actually nothing happens until you wake Angular up: try pressing the "Add result" button and the change the search string in the input, or press the "Search" button again.
1099+
If you test this code now you can easily see that, when you press the button, nothing happens. Actually nothing happens until you wake Angular up: try pressing the "Add result" button and then change the search string in the input, or press the "Search" button again.
11001100
No black magic here, you are just letting Angular digest the pizza.
11011101

11021102
There are many possible alternative solutions.
@@ -1164,16 +1164,79 @@ angular.module('AngularApp').component('search', {
11641164
});
11651165
```
11661166

1167-
The component will render anytime the custom "result-added" event will be triggered. The counter will be now updated everytime you press the "Add result" button. Remember to remove the listener once you destroy the component.
1167+
Which we could represent graphically as:
11681168

1169-
This way can also ship requirement #3.
1169+
![event-bus-trigger][25]
1170+
1171+
The component re-renders anytime the custom "result-added" event is triggered. As a consequence, the counter will be now updated everytime you press the "Add result" button.
1172+
Remember to remove the listener once you destroy the component.
1173+
1174+
Completing that we have also shipped requirement #3.
11701175
Refer to **`tag-06-using-vuex`** for what we have done so far.
11711176

11721177
> "See this? This is my boom stick! It's a 12-gauge, double-barreled Remington. S-mart's top of the line. You can find this in the sporting goods department. [...] It's got a walnut stock, cobalt blue steel and a hair trigger."
11731178
>
11741179
> <em>(Ashley J. Williams, Army of Darkness)</em>
11751180
11761181

1182+
Bonus #1: free Angular components from Angular
1183+
----
1184+
A further step in the migration could be rewriting existing Angular components as ES6 modules. You can move them into your webpack build, you can write them in a more concise style, more Vue than Angular, you are maybe learning ES6+ and want to have fun... whatever. Or maybe you are not interested in any restyling (you already write Angular component that way or you prefer to directly migrate the component to Vue). Either is fine.
1185+
Just in case, you can move for example `angularApp/components/search.js` into `vueApp/src/ngVueBridgeCode/components/Search/index.js`, and rewrite it as:
1186+
1187+
**ngVueBridgeCode/components/Search/index.js**
1188+
```javascript
1189+
import template from './index.html';
1190+
import SafeApply from '@/ngVueBridgeCode/utilities/safeApply';
1191+
1192+
export default {
1193+
template: template,
1194+
bindings: {
1195+
countLabel: '@'
1196+
},
1197+
controller: class SearchComponentController {
1198+
/** @ngInject */
1199+
constructor($scope, searchService, VuexStore, VueAngularEventBus) {
1200+
this.scope = $scope;
1201+
this.searchService = searchService;
1202+
this.$store = VuexStore;
1203+
this.VueAngularEventBus = VueAngularEventBus;
1204+
this.render = SafeApply.bind(this.scope);
1205+
this.searchInput = '';
1206+
}
1207+
1208+
search (searchParam) {
1209+
this.searchService.query(searchParam).then(this.render);
1210+
}
1211+
1212+
resultsCount () {
1213+
return this.$store.getters['resultsCount'];
1214+
}
1215+
1216+
$onInit() {
1217+
this.VueAngularEventBus.$on('result-added', this.render);
1218+
}
1219+
1220+
$onDestroy() {
1221+
this.VueAngularEventBus.$off('result-added', this.render);
1222+
}
1223+
}
1224+
};
1225+
```
1226+
1227+
**Note**: to use `SafeApply` we do not need the wrapping utilities service anymore.
1228+
1229+
Instantiate it as an Angular component:
1230+
1231+
**ngVueBridgeCode/ngVueComponentsModule.js**
1232+
```javascript
1233+
import Search from '@/ngVueBridgeCode/components/Search/index.js';
1234+
ngVueComponentsModule.component('search', Search);
1235+
```
1236+
1237+
And delete all files and code related to the original component. Our Angular app is reducing to its bare bones. See `tag-07-es6-components`.
1238+
1239+
11771240

11781241

11791242
[1]: screenshots/01-simple_app.png
@@ -1200,3 +1263,4 @@ Refer to **`tag-06-using-vuex`** for what we have done so far.
12001263
[22]: https://docs.angularjs.org/guide/scope#scope-life-cycle
12011264
[23]: screenshots/08-safe_apply.png
12021265
[24]: screenshots/09-event_bus.png
1266+
[25]: screenshots/10-event_bus_triggers.png

code/angularApp/components/search.js

Lines changed: 0 additions & 34 deletions
This file was deleted.

code/index.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@
1111
<body>
1212
<div id="angular-app-container" ng-app="AngularApp">
1313
<header>
14-
<search></search>
14+
<search count-label="results count"></search>
1515
</header>
1616

1717
<vue-app-container></vue-app-container>
1818
</div>
1919

2020
<script src="vendor/angular.min.js"></script>
2121
<script src="angularApp/angularApp.js"></script>
22-
<script src="angularApp/components/search.js"></script>
2322
<script src="angularApp/components/innerDetail.js"></script>
2423

2524
<!-- ngVue components -->

0 commit comments

Comments
 (0)