You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Sometimes you have to say "stop!" and decide it's time to migrate to a warmer and sunnier place.
@@ -163,7 +159,7 @@ code
163
159
|_index.html
164
160
```
165
161
166
-
> **Please note:** here I will not initialize the Vue app through vue-cli. I am reusing a Webpack custom configuration which suites my needs. Nevertheless, everything should work the same way if you are using vue-cli.
162
+
> **Please note**: here I will not initialize the Vue app through vue-cli. I am reusing a Webpack custom configuration which suites my needs. Nevertheless, everything should work the same way if you are using vue-cli.
167
163
168
164
See tag **`tag-02-app-directory-structure`** (with emtpy folders and files).
169
165
@@ -1339,6 +1335,157 @@ Sure, you can probably do the same with the `store.searchResults` property. Our
1339
1335
Refer to `tag-08-more-store`.
1340
1336
1341
1337
1338
+
Conclusions
1339
+
----
1340
+
As you have seen, once you grasp a way (I am not claiming here mine is the best or the only one) to let Angular 1.x and Vue cohabit things get easier, and you can resort to a methodology for migrating your codebase progressively.
1341
+
1342
+
> "I belong to the warrior in whom the old ways have joined the new."
1343
+
>
1344
+
> <em>(The Last Samurai)</em>
1345
+
1346
+
Again, what has been exposed in this article reflects only my opinions, and do not, in any way, constitute the best or only way to achieve the ultimate goal of renewing an old application by completely removing Angular code.
1347
+
1348
+
Oh, one more thing...
1349
+
1350
+
1351
+
Angular component nested inside Vue component
1352
+
----
1353
+
Ok, you got me! What about requirement #2? What happened to `inner-detail` once you migrated to `vue-app-container`?
1354
+
I have to be honest here, and admit we must be brave and really creative to solve the last puzzle.
1355
+
1356
+
> "That's my friend, Irishman. And the answer your question is yes - if you fight for me, you get to kill the Angular."
1357
+
>
1358
+
> <em>(William Wallace, Braveheart)</em>
1359
+
1360
+
As confirmed by one of the main repository contributors, ngVue was not designed to allow AngularJS components to be rendered inside Vue components. Someone has tried to solve the problem using `slots`, but, due to rendering differences between the frameworks, the implementation is buggy (and not recommended, because maybe in the future will be deprecated, as stated by [issue #66][27]).
1361
+
After a brief discussion (see [issue #79 on GitHub][26]), thanx to tips coming from all the participants involved (and a previous experience with Angular `injector`), I overcame the problem the way I will tell below.
1362
+
It seems to work, but it also is somehow experimental (I simply lack a deep knowledge on the subject, and I am not completely aware of possible unwanted side effects). Hence I am not sure I would really recommend it.
1363
+
Anyway, to me nesting Angular components inside Vue was an essential requirement; so I report it here to complete the picture, and give a possible solution.
1364
+
1365
+
**TL;DR**: I cooked up a Vue component which wraps and compiles an Angular component, and quietly listen for changes in the scope bound.
**#1**: `injector` is an Angular object that can be used for retrieving services as well as for dependency injection (see the [official documentation][28]). Here we are accessing to it to inject and compile a component on the fly, after the Angular application has already been bootstrapped.
1406
+
1407
+
**#2**: here we are setting the scope we will bind to the component template, extending a fresh `$scope` with the `$ctrl` object passed by the `component` prop, which basically is an object like this:
**#3**: we replace the `<div/>` tag in the Vue template with the compiled Angular component.
1416
+
1417
+
**#4**: as already seen previously, we are entangled to Angular $digest loop. To inform Angular something has changed in the object associated to its current scope, update bindings, and re-render, we are introducing a `watcher` on the `component.$ctrl` prop. Note the `{ deep: true }` option, to trigger the watcher in case you have got a complex nested object.
1418
+
1419
+
**#5**: any time the prop changes, we update the scope by merging the new object `ctrl` with the existing `scope.$ctrl` - `angular.merge` performs a **deep copy**, which is what we need here to be sure to propagate all the updates.
1420
+
1421
+
**#6**: and any time the prop changes, we call our old friend `SafeApply`, bound to an updated scope, to start a `$digest`.
1422
+
1423
+
**#7**: `this.$watch` return a function we can use to clear the watcher when the component got destroyed.
1424
+
1425
+
Then you simply use the component wherever you want to inject an Angular component:
0 commit comments