How to resolve and create Generic Classes in AngularJS Injector - dependency-injection

have a class like below,
export class SiteEventServiceType<T> {
}
How do i need to create the instance for the above class using angularjs 2 Injector.
Tried But Not working:
Injector.resolveAndCreate([SiteEventServiceType<string>]).get(SiteEventServiceType<string>);

This example was posted quite a while back at https://github.com/angular/angular/pull/1779
#Component(
selector: 'my-component',
// now providers:
injectables: const [
const Binding(
const TypeLiteral<Stream<String>>,
toFactory: MyComponent.streamFactory)
]
)
#View(
directives: const [MyChildComponent],
template: '<my-child-component></my-child-component>'
)
class MyComponent {
static Stream<String> streamFactory() => new Stream.fromIterable(['Hello']);
}
#Component(
selector: 'my-child-component'
)
#View(
template: '{{lastValue}}'
)
class MyChildComponent {
String lastValue;
MyChildComponent(Stream<String> stringStream) {
stringStream.listen((value) => lastValue = value);
}
}
See also
https://github.com/angular/angular/issues/1691 c
and the still open issue https://github.com/angular/angular/issues/5704

Related

How to instantiate/inject class declared in main component to another component

My AppComponent sample:
///other imports here
import { ApplyColor } from './../../shared/directives/applycolor';
import { SomeComponent} from './../../components/somecomponent';
#Component({
selector: 'my-app',
directives: [ApplyColor, ROUTER_DIRECTIVES],
providers: [ROUTER_PROVIDERS],
templateUrl: 'myurl.html'
})
#RouteConfig([
//routes here
{ path: '/main', name: 'Main', component: SomeComponent, useAsDefault: true },
])
export class AppComponent {
}
In order to instantiate ApplyColor in SomeComponent
Import ApplyColor
Add to directives: [ApplyColor]
Instantiate with a new keyword
Which is:
import {Component, AfterViewInit, ViewChild} from 'angular2/core';
import { ApplyColor } from './../../shared/directives/applycolor';
#Component({
selector: 'my-selector',
directives: [ApplyColor],
templateUrl: 'app/components/mycomponenturl.html'
})
export class MyComponent implements AfterViewInit {
constructor() { }
ngAfterViewInit() {
var color = new ApplyColor();
color.apply(2);
}
}
How can I instantiate/inject ApplyColor without there 3 steps above?
Directive instances are managed by Angular2. This means that you only need to specify it into the directives attribute. So if ApplyColor is a directive just add it into the directives attribute.
If ApplyColor isn't a directive, you can explicitly instantiate into the provide to the child component using #Input.
In your case, it's a bit particular since you leverage routing. In this case, you need to rely on a shared service. Such service needs to be defined when bootstrapping the application to be able to share a single instance for all components. You can set your instance of ApplyColor into a field of this service. So both component (AppComponent and SomeComponent) can access it.
Define the service
export class SharedService {
color:ApplyColor;
}
Bootstrapping the service
bootstrap(AppComponent, [ SharedService ]);
Set color from AppComponent
#Component({
(...)
})
export class AppComponent {
constructor(private service:SharedService) {
var color = new ApplyColor();
this.service.color = color;
}
}
Get color from SomeComponent
#Component({
(...)
})
export class AppComponent {
constructor(private service:SharedService) {
this.service.color.apply(2);
}
}
I have just started working angular2 but as I can understand:
import ApplyColor => you can't remove that, it required by the compiler to know which class you are referenced to
directives : [ApplyColor] => that means you will use the selector (the one you have defined in applycolor.ts) in the template (app/components/mycomponenturl.html). it is only to know where the component will be in the view.
new ApplyColor => you are creating the object yourself, it is not injected.
To inject your component,
export class MyComponent implements AfterViewInit {
constructor(private color:ApplyColor) { }
ngAfterViewInit() {
this.color.apply(2);
}
}
I hope it helped you ?

Angular2 simple DI not working

I have the following angular2 app with a simple dependency injected and it doesn't work. What am I missing?
Here's the error:
EXCEPTION: Cannot resolve all parameters for 'AppComponent'(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that 'AppComponent' is decorated with Injectable.
and the code:
import {Component} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser';
class DataService {
items: Array<any>;
constructor() {
this.items = [
{ name: 'Christoph Burgdorf' },
{ name: 'Pascal Precht' },
{ name: 'thoughtram' }
];
}
getItems() {
return this.items;
}
}
#Component({
selector: 'app',
providers: [DataService],
template: `
<ul>
<li *ngFor="#item of items">{{item.name}}</li>
</ul>
`
})
class AppComponent {
items: Array<any>;
constructor(dataService: DataService) {
this.items = dataService.getItems();
}
}
bootstrap(AppComponent, []);
Can't reproduce. I added your code to a Plunker
https://plnkr.co/edit/0DTjG5?p=preview
and it seems to work fine with or without #Injectable().
It is suggested to always add #Injectable() to services but it is only required when the service has constructor parameters.
.

Accessing a dataset map in angular2

I have the following:
.html template
<name-view data-topic='id'></name-view>
.dart component
import 'dart:html';
class NameView implements AfterViewInit
{
String topic;
void ngAfterViewInit( ) {
// datset is not reference below - works in polymer-1.x attached() method
topic = this.datset['topic'];
}
}
However, the code in ngAfterViewInit does not work.
How can I retrieve the data-topic attribute in angular2?
I wasn't able to make #Input('data-topic') work but the other ways are working
#Component(
selector: 'app-element',
template: '''
<h1>app-element</h1>
<name-view data-topic='id' topic='topicid'></name-view>
''',
directives: const [NameView])
class AppElement {}
#Component(
selector: 'name-view',
template: '''
<h1>test-element</h1>
<div>data-topic: {{topic}}</div>
<div>topic: {{topic2}}</div>
<div>topicFromRef: {{topicFromRef}}</div>
''')
class NameView implements OnInit {
#Input('data-topic')
String topic;
#Input('topic')
String topic2;
String topicFromRef;
ElementRef _elementRef;
TestElement(this._elementRef);
void ngOnInit() {
topicFromRef = (_elementRef.nativeElement as Element).dataset['topic'];
}
}
Using ElementRef is discouraged because this prevents running the code in a WebWorker or on server rendering.

How to use angular2 DynamicComponentLoader in ES6?

I'm not using typescript but ES6 and angular2 alpha39 to load a component dynamically. The following code is similar to what I have in my app. What I have noticed is angular2 does not create an instance of DynamicComponentLoader nor ElementRef and inject into the constructor. They are undefined.
How can I do the injection of DynamicComponentLoader using ES6 and angular2 alpha39?
import {Component, View, Inject, DynamicComponentLoader, ElementRef } from 'angular2/angular2'
#Component({
selector: 'dc',
bindings: [ DynamicComponentLoader ]
})
#View({
template: '<b>Some template</b>'
})
class DynamicComponent {}
#Component({
selector: 'my-app'
})
#View({
template: '<div #container></div>'
})
#Inject(DynamicComponentLoader)
#Inject(ElementRef)
export class App {
constructor(
dynamicComponentLoader,
elementRef
) {
dynamicComponentLoader.loadIntoLocation(DynamicComponent, elementRef, 'container');
}
}
If you want to write code in ES7, I think the most concise approach to specify injections at this time is to use static getter for parameters:
import {Component, View, DynamicComponentLoader, ElementRef } from 'angular2/angular2'
#Component({
selector: 'my-app'
})
#View({
template: '<div #container></b>'
})
export class App {
static get parameters() {
return [[DynamicComponentLoader], [ElementRef]];
}
constructor(dynamicComponentLoader, elementRef) {
dynamicComponentLoader.loadIntoLocation(DynamicComponent, elementRef, 'container');
}
}
See this plunker
If you want to write code in ES6, which doesn't support decorators, you must also use static getter for annotations property. In this case you must import ComponentMetadata and ViewMetadata instead of Component and View For example:
import {ComponentMetadata, ViewMetadata, DynamicComponentLoader, ElementRef } from 'angular2/angular2';
export class App {
static get annotations() {
return [
new ComponentMetadata({
selector: 'app'
}),
new ViewMetadata({
template: '<div #container></b>'
})
];
}
static get parameters() {
return [[DynamicComponentLoader],[ElementRef]];
}
constructor(dynamicComponentLoader, elementRef) {
dynamicComponentLoader.loadIntoLocation(DynamicComponent, elementRef, 'container');
}
}
See this plunker

Simple AngularDart component Failing

I have this minimal code for an Angular Dart component, I've even written it in the same file, but I cant get it to work.
import 'package:angular/angular.dart';
import 'package:angular/application_factory.dart';
void main() {
applicationFactory().addModule(new TT()).run();
}
class TT extends Module
{
TT ()
{
bind(SimpleString);
}
}
#Component(
selector: 'simplestring',
publishAs: 'cmp',
template: '<div> {{cmp.str}} </div>'
)
class SimpleString
{
#NgAttr('str')
String str;
}
Html body
<body>
<simplestring str='hola'></simplestring>
</body>
This should show "hola", but nothing is happening.
publishAs:is deprecated and not interpreted any more since AngularDart 1.0
Use the property name directly:
#Component(
selector: 'simplestring',
template: '<div> {{str}} </div>'
)
class SimpleString
{
#NgAttr('str')
String str;
}

Resources