javascript - Angular 2 service injection using TypeScript 1.5 - Stack Overflow

admin2025-04-21  0

I'm trying to get a very basic, functional structure set up for Angular 2. It will have only the most basic API elements so that as the framework advances, I can advance my structure.

Currently, I'm at my wit's end as to how to perform the simple act of passing services. Here is some example source, taken right from the ments of the most recent DefinitelyTyped file:

class Greeter {
    greet(name: string) {
        return 'Hello ' + name + '!';
    }
}
@Component({
    selector: 'greet',
    appInjector: [Greeter]
})
@View({
    template: `{{greeter.greet('world')}}!`
})
class HelloWorld {
    greeter: Greeter;
    constructor(greeter: Greeter) {
        this.greeter = greeter;
    }
}
bootstrap(HelloWorld);

As you can see, I'm using Typescript 1.5 in this example.

I have tried to inject the Greeting service in the Component annotation using hostInjector, injectibles and appInjector. I've also tried adding it to the second argument of the bootstrap call, as in bootstrap(HelloWorld, [Greeter]).

In all cases I get this error message when trying to run it in the browser:

Error during instantiation of Token(ComponentRef)!. ORIGINAL ERROR: Cannot resolve all parameters for HelloWorld(?). Make sure they all have valid type or annotations.

Of course, if I remove greeter: Greeter argument from the constructor, the error in question goes away and is replaced by other, expected errors further down the chain.

Ideas?

EDIT

I updated the title of this question to specify that I am using TypeScript 1.5

I'm trying to get a very basic, functional structure set up for Angular 2. It will have only the most basic API elements so that as the framework advances, I can advance my structure.

Currently, I'm at my wit's end as to how to perform the simple act of passing services. Here is some example source, taken right from the ments of the most recent DefinitelyTyped file:

class Greeter {
    greet(name: string) {
        return 'Hello ' + name + '!';
    }
}
@Component({
    selector: 'greet',
    appInjector: [Greeter]
})
@View({
    template: `{{greeter.greet('world')}}!`
})
class HelloWorld {
    greeter: Greeter;
    constructor(greeter: Greeter) {
        this.greeter = greeter;
    }
}
bootstrap(HelloWorld);

As you can see, I'm using Typescript 1.5 in this example.

I have tried to inject the Greeting service in the Component annotation using hostInjector, injectibles and appInjector. I've also tried adding it to the second argument of the bootstrap call, as in bootstrap(HelloWorld, [Greeter]).

In all cases I get this error message when trying to run it in the browser:

Error during instantiation of Token(ComponentRef)!. ORIGINAL ERROR: Cannot resolve all parameters for HelloWorld(?). Make sure they all have valid type or annotations.

Of course, if I remove greeter: Greeter argument from the constructor, the error in question goes away and is replaced by other, expected errors further down the chain.

Ideas?

EDIT

I updated the title of this question to specify that I am using TypeScript 1.5

Share Improve this question edited Jun 20, 2015 at 17:28 Pete Gardner asked Jun 19, 2015 at 20:00 Pete GardnerPete Gardner 5451 gold badge5 silver badges17 bronze badges 1
  • Not yet. The error still happens. I'm still wondering if it's a type definition problem. – Pete Gardner Commented Jun 26, 2015 at 20:19
Add a ment  | 

6 Answers 6

Reset to default 2

I had a similar problem when using typescript 1.5.0-beta and angular 2.0.0-alpha.28 (not sure if the versions are strictly relevant) with gulp.

You need to tell the typescript piler to export metadata so the DI injector knows what to do. I did this by adding emitDecoratorMetadata and experimentalDecorators to my tsconfig.json:

{
    "pilerOptions": {
        "module": "monjs",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "sourceMap": true,
        "target": "es5"
    }
}

After that you can add appInjector: [Greeter] to your @Component declaration like you've done or to the bootstrap declaration:

bootstrap(HelloWorld, [Greeter]);

Regarding TS2348. I got the same error. Got rid of ComponentAnnotaion and ViewAnnotation and this helped:

import {
  bootstrap,
  Component,
  View
} from 'angular2/angular2';

I hope your code will work fine in typescript 1.5 release. Right now, you should use Inject annotation in typescript 1.5.0-beta.

import {
  ComponentAnnotation as Component,
  ViewAnnotation as View, bootstrap,
  Inject
} from 'angular2/angular2';

@Component({
  selector: 'app',
  hostInjector: [Service]
})
@View({
  template: '{{greeting}} world!'
})
class App {
  constructor(@Inject(Service)service: Service) {
    this.greeting = service.greeting();
    setTimeout(() => this.greeting = 'Howdy,', 1000);
  }
}

class Service {
  greeting() {
    return 'Hello';
  }
}

bootstrap(App);

More a workaround than a solution, but if you move your service definition to a separate file (greeting.ts), and import it

import {Greeting} from 'greeting';

then the injector works correctly. This is built using tsc from the mand line (taken from the 5 min quickstart on angular.io)

tsc --watch -m monjs -t es5 --emitDecoratorMetadata  app.ts

With angular2.0.0-alpha.32 I acplished this with

/// <reference path="../../typings/angular2/angular2.d.ts" />

import {Component, View, bootstrap, NgFor} from 'angular2/angular2';
import {MyService} from 'js/services/MyService';

// Annotation section
@Component({
    selector: 'my-app',
    viewInjector: [MyService]
})
@View({
    templateUrl: 'templates/my-app.tpl.html',
    directives: [NgFor]
})

class MyComponent {
    mySvc:MyService;

    constructor(mySvc:MyService) {
        this.mySvc = mySvc;
    }

    onInit() {
        this.mySvc.getData();
    }
}   

bootstrap(MyComponent, [MyService]);

Here is the code, straight out of the plnkr.co template for injecting a service http://plnkr.co/edit/m5sHWWFmgYPrfsMv0u2r

import {
  ComponentAnnotation as Component,
  ViewAnnotation as View, bootstrap
} from 'angular2/angular2';

@Component({
  selector: 'app',
  viewInjector: [Service]
})
@View({
  template: '{{greeting}} world!'
})
class App {
  constructor(service: Service) {
    this.greeting = service.greeting();
    setTimeout(() => this.greeting = 'Howdy,', 1000);
  }
}

class Service {
  greeting() {
    return 'Hello';
  }
}

bootstrap(App);
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745242007a292067.html

最新回复(0)