Angular 2 component inside Angular 1? - javascript

I want to add an Angular 2 component inside my Angular 1 controller, so the Angular 1 controller is a parent and Angular 2 component is a child. I would like a child and parent be able to exchange data between each other like using #Input and #Output in Angular 2. Does anyone know how to do that?

This should be done using Upgrade Adapter module (shipped with Angular 2).
The steps should be:
1. Bootstrap you app using the adapter, instead of ng-app
2. Downgrade your angular 2 component and wrap it with Angular 1 directive.
You can use my super simple Todo app example (just look into the commits for the steps inside 'upgrade' branch):
Todo-app example
This is how your bootstrap file look like:
declare var angular: any;
import {UpgradeAdapter} from 'angular2/upgrade';
import {TodoList} from "./components/todo-list";
import {TodoInput} from "./components/todo-input";
import {TodoApp} from "./components/todo-app";
let adapter = new UpgradeAdapter();
angular.module('todoListWorkshopApp').directive('todoList', adapter.downgradeNg2Component(TodoList));
angular.module('todoListWorkshopApp').directive('todoInput', adapter.downgradeNg2Component(TodoInput));
angular.module('todoListWorkshopApp').directive('todoApp', adapter.downgradeNg2Component(TodoApp));
adapter.bootstrap(document.body, ['todoListWorkshopApp']);
And this is an example of the controller's template (Angular 1):
<div>
<todo-input (on-item-added)="add($event)"></todo-input>
<todo-list [todos]="todos"></todo-list>
</div>

Related

Render HTML string template that refers internal angular components

I'm trying to render an HTML string template that refers internal angular components & directives which are part of the app.
The question is that bind is lost in components and I don't know how to "preload" directives just like we do with components through entryComponents.
I created a demo project to better explain/demonstrate what I'm trying to achieve with dynamic templates:
There are 3 samples in my demo project:
Sample #1 - Common usage scenario - components are referenced inside my main component and work as expected
Sample #2 - [innerHTML] which obviously doesn't meet the requirements.
Sample #3 - Dynamic render which doesn't work for components since bind is broken and directives are not processed.
https://stackblitz.com/edit/angular-dynamic-html-1pcrbx?file=app/app.component.html
#Component({
})
class MyComponent {
constructor() {}
private myTemplate = `
<hello name="TEST"></hello>
<div test>My div referencing a custom directive</div>
`;
}
So, is it possible to do what I'm tying to do?
What am I doing wrong?

Manually mount a globally registered Vue component into a legacy app?

I am converting an AngularJS project to Vue 2.
My strategy is to have AngularJS handle routing, and slowly swap out individual components within each angular view.
In my main.ts file, I'm importing and defining global components like this:
import LoginForm from './components/LoginForm.vue';
Vue.component('LoginForm', LoginForm);
When the relevant Angular controller loads, I'd like to run some javascript to manually mount the Vue component.
Is this a good approach?
How can I manually mount a previously registered component?
Vue.somehowGetComponent('LoginForm').mountTo('#login-form');
I wouldn't register it as a global component for this purpose. Simply import it, then create an instance of it and mount it. eg.
// import the component
import LoginForm from './components/LoginForm.vue';
// If you haven't already, must call `Vue.extend` on LoginForm before its instantiation
const myLoginForm = new LoginForm();
// mount to your legacy app
myLoginForm.$mountTo(document.getElementById('login-form'));
The key here was calling Vue.extend on my imported component:
In Vue.js:
// main.ts
import LoginForm from './components/LoginForm.vue';
window.LoginForm = Vue.extend(LoginForm)
Then in the AngularJS controller:
angular.module('app').controller(function(){
var vue = new window.LoginForm();
vue.$mount('#login-form');
});

passing reference of angular 5 component to angular js

I have made a directive in angular 5 which uses ngTemplateOutlet, thus my directive then requires the name of a component, which it then renders dynamically.
<back-container [componentOutlet]='dynamicComponent' [componentOutletContext]="{'data' : data}"></back-container>
Now this directive i am using in a component, which takes the reference of the component to be rendered as input.
<tile [dynamicComponent]='instance>
where instance is
instance = SpeedometerComponent;
This component i want to use in angular js application, thus i am using downgradeComponent to downgrade the component and use it in angular js.
.directive(
'Tile',
downgradeComponent({ component: TileComponent }) as angular.IDirectiveFactory)
How to pass component as an input in angular js application?
The component which i have to pass in angular js is another angular 5 component

Getting error " emitted value instead of an instance of error while compiling template " while implement vue table

I am trying to implement a Vue table by using Vue table plugin in my application using node module. Here I am getting an error while using all Vue table component. Here I install all Vue table plugin using npm and import them in my custom component.
My snippet of code is attached here with.
import Vuetable from 'vuetable/src/components/Vuetable.vue';
import VuetablePagination from 'vuetable/src/components/VuetablePagination.vue';
import VuetablePaginationDropdown from 'vuetable/src/components/VuetablePaginationDropdown.vue';
Here first I import the vue table plugin into my component.
Then register such component into my custom component into vue instance.
data () {
return{
columns: [
'name',
'nickname',
'email',
'birthdate',
'gender',
'__actions'
]
}
},
components : {
Vuetable,
VuetablePagination,
VuetablePaginationDropdown
}
And in template section i write this block of code.
<vuetable
api-url="http://vuetable.ratiw.net/api/users"
table-wrapper="#content"
pagination-component="vuetable-pagination"
:fields="columns">
</vuetable>
first try to import vue and use component like sample below
import vue from 'vue';
vue.use(Vuetable);
vue.use(VuetablePagination);
vue.use(VuetablePaginationDropdown);
You might need to debug each instance components html structure. You could be missing one of these:
A closing tag arrow > or closing tag slash / in one of your elements.
Absence of single root element.

Cannot use Angular 1 directive in Angular 2 app using upgradeNg1Component()

I am trying to make a hybrid angular app using Angular 1 & 2. I have a simple angular 1 directive:
var sample = angular.module('interestApp',[]);
sample.directive('myComp', function() {
return {
scope:{},
restrict: 'E',
template: '<div>My name is </div>'
}
});
I want to use this directive in my angular 2 app. So I convert it using upgradeNg1Component() like this:
const upgradeAdapter: UpgradeAdapter = new UpgradeAdapter();
upgradeAdapter.bootstrap(document.body, ['interestApp']);
#Component({
selector: 'angular2',
template: '<myComp></myComp>',
directives: [upgradeAdapter.upgradeNg1Component('myComp')]
})
I am getting this error when I run it though:
EXCEPTION: No provider for $scope! (function (scope, elementRef)
Can anyone help with this? Or if anyone knows any other way of using angular 1 directive in angular 2 application that would be really helpful.
You code looks good so far, but it seems like there's one part missing. While you upgrade your ng1 component to use it in your Angular 2 component with the selector angular2 (which I would suggest to change), you don't downgrade that Angular 2 component again to actually use it in your bootstrapped Angular 1 application.
That's something you always have to do as long as you're in the process of upgrading your app. In order to get your Angular 2 component instantiated, you need to use it in your A1 as a directive and therefore it needs to be downgraded. So you'd need to do sth. like:
#Component({
selector: 'my-ng2-component',
template: '<myComp></myComp>',
directives: [upgradeAdapter.upgradeNg1Component('myComp')]
})
class MyNg2Component {
}
angular.module('interestApp', [])
.directive('myComponent', {...})
.directive('myNg2Component', upgradeAdapter.downgradeNg2Component(MyNg2Component);
upgradeAdapter.bootstrap(document.body, ['interestApp']);
As soon as you're done with upgrading you can remove all the Angular 1 specifc parts and the downgrading mechanisms.
In your HTML, are you referencing both versions of the component/directive?
For me, this would occur any time that I referenced the Angular2 version of a component that was both:
downgraded to AngularJS
referenced an upgraded AngularJS directive in its template.
In my case, I defined <ng2-component> for NG2 and <downgraded-ng2-component> for NG1 and was referencing them both in my HTML. This resulted in the error.
I found that in my use of Angular 2.0.0-beta.0 that I have to avoid using the original Angular2 component when it met both cases (1) and (2) from above.

Categories