Angular2, how to use #Host on ES6 components - dependency-injection

I don't see an example on how to use accomplish what Host does (inject parent reference into child) in ES6.
#Component({ ... })
class PlayButton {
constructor(#Host() playerService: PlayerService) {
}
}
Any idea on how we could achieve this?

There is a Host variable, which may be used with any Directives.Not sure if there is #Host decorator.
Also if you have to inject some service you may use providers in the component decorator.
you may look into Angular API for reference.
For Host implementation you may look into Attribute Directives implementation.
Update
you may try ContentChildren decorator.
#Directive({
selector: 'someDir'
})
class SomeDir {
#ContentChildren(ChildDirective) contentChildren: QueryList<ChildDirective>;
ngAfterContentInit() {
// contentChildren is set
}
}
For reference you may check Angular API

Related

Multiple instances of one service

I have a simple service
import { Injectable } from '#angular/core';
import { Subject } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class CompToCompService {
private data = new Subject<any>();
data$ = this.data.asObservable();
constructor() { }
Send(value: any) {
this.data.next(value);
}
}
I use it to sling some light data back and forth between components.
I have however found myself needed to use it twice in the same component to send data and use different components to listen. As angular services are now by default singletons everything is being jumbled together.
Is it possible to create different instance of the server and if so how do I get the listening components to listen to the right instance?
If not what's the best way to accomplish what I am trying to do. I am trying to avoid creating a tiny service like that for every piece of communication I need to do. I know of events but my communications are across the routing-outlet and events don't seem to like that.
Create a parent component with two or more child components.
in each child component use
providers: [serviceName]
Then you will have tow instance of service .
but you must work with each instance in their component

use service as decorator

Is there a way to do a static decorator on routes that check certain logics before loading?
example
have a auth decorator
#Injector()
class Auth{
Auth(){
if (isLoggedIn){
proceed();
}else{
showLoginRoute();
}
}
}
and use like
#Auth()
#Component(
selector: 'auth-view',
styleUrls: const ['login_component.css'],
template:
'<router-outlet name="dashboard" [routes]="routes.authView_routes"></router-outlet>',
directives: const [materialDirectives, routerDirectives, coreDirectives],
providers: const [r.Routes, materialProviders, Auth],
)
class Dashboard{
....
}
I know what i want to do but just not sure how to get it done. Currently i am importing services across several components and doing lots of repetition and i want to avoid that as much as possible.
Dart doesn't support anything like decorators in TS.
What might work for you is code generation like it's done in build_value, json_serializable, ...
https://github.com/dart-lang/build

Angular2 Inject components into other components

I'm messing around with Angular2 and I'm wanting the ability to inject one component into another based on the bootstrapped bindings.
class HelloComponent {
name: string;
}
#Component({
selector: 'hello'
}
#View({
template: `<h3>Hello {{ name }}</h3>`
})
class HelloBobComponent extends HelloComponent {
constructor() {
this.name = 'Bob';
}
}
#Component({
selector: 'app'
}
#View({
directives: [HelloComponent]
template: `<h1>Welcome to my Angular2 app</h1>
<hello></hello>`
}
class AppComponent {
}
bootstrap(AppComponent, [
bind(HelloComponent).toClass(HelloBobComponent)
]);
Here I'm using HelloComponent as a token that I want Angular2's Injector to resolve HelloBobComponent. I'm doing this so that I can swap components in and out based on the current app configuration. The above example obviously doesn't work. Is this possible using one of the frameworks decorators? I haven't found an answer yet digging though blogs or the source.
edit: To clarify, how do I get the directives property on the View decorator to treat HelloComponent as a di token instead of a type.
This is currently not supported as of alpha37. The compiler resolves directives passed in the View decorator by either type or binding but does not look up from the parent injector.
For example:
#View({
url: '...',
directives: [
Directive1,
bind(Directive2).toClass(Directive2Impl),
]
})
The intention for the "directives" property here was only to prevent selector naming collision. Later bind support was added to aid in testing.
The only solution I can think of without editing the compiler function would be to maintain an external Injector and resolve types on component declaration.

Dependency injection: Angular 2 not working

I'm following the tutorials display-data in angular.io.
I introduced a new class FriendsService to separate the controller logic and model concern. I Called FriendsService class in DisplayComponent class by using dependency injection, the dependency injection not working.
There's no errors in the console. The page doesn't display the component. This is the line causing the component not to display on the page.
constructor(friendsService: FriendsService)
The page loads and displays the components (display) if change the constructor to:
constructor()
I'm using angular2.alpha.34 , Typescript, ES6.
I solved it. Eclipse-Plugin was causing the issue. The plugin wasn't generating the ES5 complaint correct code.
I used "tsc --watch -m commonjs -t es5 --emitDecoratorMetadata app.ts" command described in angular.io website.
The eclipse-plugin generated code and the command "tsc" generated code is slightly different.
When using the "tsc" command I was achieving the expected behavior.
First you have to define the Service before that any component or directive.
If you have something like this
class Component {
constructor(svc: Service) {
}
}
class Service {
}
It will fail. In cases like this you should use fordwardRef or you just can declare it before your component.
class Service {
}
class Component {
constructor(svc: Service) {
}
}
Another thing is that you have to inject your service using viewBindings (see ComponentAnnotation documentation).
class Service {
}
#Component({
viewBindings: [Service]
})
class Component {
constructor(svc: Service) {
}
}
And you are good to go. I hope it helps.

Custom route class

In symfony 1.4 you could define a custom route class, where you override the generation of url with custom logic, for example:
custom:
class: sfDoctrineRouteCollection
options:
model: Custom
prefix_path: /custom/category/:category_id
column: id
route_class: CustomDoctrineRoute
class CustomDoctrineRoute extends sfDoctrineRoute
{
public function generate($params, $context = array(), $absolute = false)
{
if (!isset($params['category_id'])) {
$params['category_id'] = sfContext::getInstance()->getRequest()->getParameter('category_id');
}
return parent::generate($params, $context, $absolute);
}
}
This allows to write url_for('custom_show', array('id'=> $object['id'])) and not bother about context dependent parameters (category_id).
How do you approach this is symfony2?
I can think of 2 approaches to this. The first, and simplest, is to extend the Router class with your own and tell symfony to use your class in your parameters.yml or config.yml:
parameters:
router.class: Company\CoreBundle\Routing\MyCustomRouter
There's a more powerful (read: complicated) solution which allows you to define more dependencies on your router class by overriding or extending the whole router service. There is a bundle that does this called BeSimpleI18nRoutingBundle which you can look at to see how it's done.
Specifically, notice the CompilerPass where they replace the default router service with their own. You then have to implement the RouterInterface in your own router class. In this particular bundle they inject the original default router (after having renamed it in the compiler pass).

Resources