angular - Greška: (SystemJS) Ne mogu riješiti sve parametre za JobActionsComponent: (?)


Kada koristim frontend-maven-plugin zajedno s GruntFile.js, gdje koristim sljedeće verzije Node i NPM:

                 <executions>
                    <execution>
                        ...
                        <configuration>
                            <nodeVersion>v6.7.0</nodeVersion>                           
                            <npmVersion>3.10.8</npmVersion>
                        </configuration>
                    </execution>
                    <execution>
                        <id>npm install</id>
                        ...
                    </execution>
                    <execution>
                        <id>grunt build</id>
                        <goals>
                            <goal>grunt</goal>
                        </goals>
                        <phase>prepare-package</phase>                            
                    </execution>
                </executions>

Dobivam pogrešku runtime error u pregledniku:

(SystemJS) Can't resolve all parameters for JobActionsComponent: (?).

Ali sljedeći kod radi s WebStorm 2016.2.4 IDE, gdje koristim iste verzije

  • Čvor v6.7.0
  • NPM 3.10.8
  • TypeScript verzija 1.8.10 (uključeno)

app.module.ts

import { NgModule }       from '@angular/core';
import { BrowserModule }  from '@angular/platform-browser';
import { FormsModule }    from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent }         from './app.component';
import { JobListComponent }      from './jobs/job-list.component';
import { KeysPipe }          from './jobs/keys.pipe';
import { JobService }          from './jobs/job.service';
import { routing } from './app.routes';
import {JobActionsComponent} from "./jobs/job-actions.component";
import {JobStopComponent} from "./jobs/job-stop.component";
import { JobStartComponent } from './jobs/job-start.component';
import {RouterModule} from "@angular/router";

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    routing,
    RouterModule
  ],
  declarations: [
    AppComponent,
    JobListComponent,
    JobActionsComponent,
      JobStopComponent,
    JobStartComponent,
    KeysPipe
  ],
  providers: [
    JobService
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule {
}

job-actions.component.ts

import { Component, OnInit, Inject } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Router, ActivatedRoute, Params } from '@angular/router';

@Component({
    selector: 'my-app',
    template: `
    <div>
      <header>
        <div>
          <!-- Title -->
          <main class="mdl-layout__content">
            <h1 class="header-text">Spring Batch {{name}}</h1>
          </main>
          <div>
            <ul>
                <li>
                        <a [routerLink]="['/stop_job', name]">Stop {{name}}</a>
                </li>
                <li>
                        <a [routerLink]="['/start_job', name]">Start {{name}}</a>
                </li>
                <li>
                        <a>Run Manual {{name}}</a>
                </li>
                <li>
                        <a>Job Instances for {{name}}</a>
                </li>
            </ul> 
          </div>
        </div>
      </header>
    </div>
    `,
    // Providers
    //providers: [JobService]
})
// Component class implementing OnInit
export class JobActionsComponent implements OnInit {
    // Private properties for binding
    private name;

    //what worked was to import Inject and explicity state @Inject
    constructor( @Inject(ActivatedRoute) private route: ActivatedRoute) {}

    // Load data ones componet is ready
    ngOnInit() {

        this.name = this.route.snapshot.params['name'];
        console.log(this.name)
    }

}

pacakge.json

{
  "name": "mec-irs",
  "version": "1.0.0",
  "scripts": {
    "start": "tsc && concurrently \"tsc -w\" \"lite-server\" ",
    "lite": "lite-server",
    "postinstall": "typings install",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "typings": "typings"
  },
  "licenses": [
    {
      "type": "MIT",
      "url": "https://github.com/angular/angular.io/blob/master/LICENSE"
    }
  ],
  "dependencies": {
    "grunt": "1.0.1",
    "grunt-contrib-copy": "1.0.0",
    "grunt-contrib-uglify": "1.0.1",
    "grunt-contrib-watch": "1.0.0",
    "grunt-ts": "5.5.1",
    "@angular/common": "~2.0.2",
    "@angular/compiler": "~2.0.2",
    "@angular/core": "~2.0.2",
    "@angular/forms": "~2.0.2",
    "@angular/http": "~2.0.2",
    "@angular/platform-browser": "~2.0.2",
    "@angular/platform-browser-dynamic": "~2.0.2",
    "@angular/router": "~3.0.2",
    "@angular/upgrade": "~2.0.2",
    "angular-in-memory-web-api": "~0.1.5",
    "bootstrap": "^3.3.7",
    "core-js": "^2.4.1",
    "reflect-metadata": "^0.1.8",
    "rxjs": "5.0.0-beta.12",
    "systemjs": "0.19.39",
    "zone.js": "^0.6.25"
  },
  "devDependencies": {
    "concurrently": "^3.0.0",
    "lite-server": "^2.2.2",
    "typescript": "^2.0.3", 
    "typings":"^1.4.0"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  }
}

GruntFile.js

module.exports = function(grunt) {
  grunt.initConfig({
    ts: {
      default : {
        src: ["**/*.ts", "!node_modules/**"]
      },
      options : {
    experimentalDecorators: true
      }
    }
  });
  grunt.loadNpmTasks("grunt-ts");
  grunt.registerTask("default", ["ts"]);
};

Pokušao sam promijeniti verziju Typescripta u package.json na 1.8.10, kao što je u WebStorm IDE-u. Evo izlaza kompilacije Typescripta s Maven dodatkom:

[INFO] --- frontend-maven-plugin:1.1:grunt (grunt build) 
[INFO] Running 'grunt --no-color'
[INFO] Running "ts:default" (ts) task
[INFO] Compiling...
[INFO] Cleared fast compile cache for target: default
[INFO] ### Fast Compile >>app/app.component.ts
[INFO] ### Fast Compile >>app/app.module.ts
[INFO] ### Fast Compile >>app/app.routes.ts
[INFO] ### Fast Compile >>app/jobs/job-actions.component.ts
[INFO] ### Fast Compile >>app/jobs/job-list.component.ts
[INFO] ### Fast Compile >>app/jobs/job-start.component.ts
[INFO] ### Fast Compile >>app/jobs/job-stop.component.ts
[INFO] ### Fast Compile >>app/jobs/job.routes.ts
[INFO] ### Fast Compile >>app/jobs/job.service.ts
[INFO] ### Fast Compile >>app/jobs/job.ts
[INFO] ### Fast Compile >>app/jobs/keys.pipe.ts
[INFO] ### Fast Compile >>app/main.ts
[INFO] ### Fast Compile >>typings/globals/core-js/index.d.ts
[INFO] ### Fast Compile >>typings/globals/jasmine/index.d.ts
[INFO] ### Fast Compile >>typings/globals/node/index.d.ts
[INFO] ### Fast Compile >>typings/index.d.ts
[INFO] Using tsc v2.0.3
[INFO] 
[INFO] 
[INFO] 
[INFO] TypeScript compilation complete: 3.43s for 16 TypeScript files.
[INFO] 
[INFO] Done.

Odgovor #1

Da bi ovo funkcioniralo, morao sam eksplicitno dodati @Inject u konstruktor na sljedeći način:

constructor(@Inject(JobService) private jobService: JobService, @Inject(ActivatedRoute) private route: ActivatedRoute) {}

Ažurirao sam gore navedeni job-actions.component.ts.

Ali zapravo, morao sam koristiti @Inject u svim svojim konstruktorima. To nisam morao raditi u svom WebStorm okruženju. Ovo je JobService.ts gdje sam morao izričito dodati @Inject (Http):

import {Injectable, Inject}    from '@angular/core';
import {Http, Response} from '@angular/http';
import 'rxjs/add/operator/map';

// Decorator to tell Angular that this class can be injected as a service to another class
@Injectable()
export class JobService {

      // Class constructor with Jsonp injected
      constructor( @Inject (Http)private http:Http) { }

      // Base URI for Spring Batch Admin
      private jobsUrl = 'http://localhost:8081/batch/';

      private mecUrl = 'http://localhost:8080/mec/admin/irs/jobs/';

    // Get the list of jobs
    listJobs() {
        // RESTful service, list of jobs:
        // http://localhost:8081/batch/jobs.json
        const endPoint = 'jobs.json'

        // Return response
        return this.http.get(this.jobsUrl)
            .map(res => res.json().jobs.registrations);

    }

    // Stop Spring Batch Job by its name
    stopJobByName(name: string) {
        const endPoint = name + '/stopIrsJobPoller';
        return this.http.get(this.mecUrl + endPoint)
            .map(res => <string>res.json());
    }

    // Start Spring Batch Job by its name
    startJobByName(name: string) {
        console.log("IN startJobByName() called " + name);
        const endPoint = name + '/startIrsJobPoller';
        console.log(this.mecUrl + endPoint);
        return this.http.get(this.mecUrl + endPoint)
            .map(res => <string>res.json());
    }

    // Run Spring Batch Job manually by its name
    manualJobRunByName(name: string) {
        const endPoint = name + '/jobRequest';
        return this.http.get(this.mecUrl + endPoint)
            .map(res => <string>res.json());
    }
}