简体   繁体   中英

Angular Material Dialog: Error: StaticInjectorError[TicketService]

I got a problem with providers declaration. The main logic is that you create a service and you declare this service on AppComponent which is used by the children. But When I use parent service declaration, i got error.

App component has providers so I should not declare providers tag in CreateComponent. And also header uses this providers successfully but create got problem with that. If you need more details about code, I can provide it.

App.Component.ts

import { Component } from '@angular/core';
import { TicketService } from './tickets/ticket.service';
import { Ticket } from './tickets/ticket/ticket.model';
import { UserService } from './users/user.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers:[TicketService,UserService]
})
export class AppComponent {


  constructor() { }

  ngOnInit() {

  }

}

App.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { TicketsComponent } from './tickets/tickets.component';
import { TicketComponent } from './tickets/ticket/ticket.component';
import { TicketDetailComponent } from './tickets/ticket-detail/ticket-detail.component';
import { UpdateTicketComponent } from './tickets/update-ticket/update-ticket.component';
import { Routes, RouterModule } from '@angular/router';
import { CommentsComponent } from './tickets/comments/comments.component';
import { CommentComponent } from './tickets/comments/comment/comment.component';
import {NgxPaginationModule} from 'ngx-pagination';
import { UsersComponent } from './users/users.component';
import { UpdateWindowComponent } from './tickets/update-ticket/update-window/update-window.component';
import { MatDialogModule, MatNativeDateModule } from '@angular/material';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { CreateTicketComponent } from './create/create-ticket.component';


const appRoutes: Routes = [
  {    path: '', component: TicketsComponent  },
  {    path: 'dashboard', component: TicketsComponent  },
  {    path: 'ticket/:id', component: UpdateTicketComponent },
  {    path: 'create', component: CreateTicketComponent }
];

@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    TicketsComponent,
    TicketComponent,
    TicketDetailComponent,
    CreateTicketComponent,
    UpdateTicketComponent,
    CommentsComponent,
    CommentComponent,
    UsersComponent,
    UpdateWindowComponent
    ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    NgxPaginationModule,    
    FormsModule,
    HttpModule,
    MatNativeDateModule,
    ReactiveFormsModule,
    RouterModule.forRoot(appRoutes),
    MatDialogModule
  ],
  providers: [],
  bootstrap: [AppComponent],
  entryComponents: [UpdateWindowComponent,UpdateTicketComponent]

})
export class AppModule { }

header.component.ts

import { Component, OnInit } from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { TicketService } from '../tickets/ticket.service';
import { Ticket } from '../tickets/ticket/ticket.model';
import { NgForm } from '@angular/forms';
import { UserService } from '../users/user.service';
import { CreateTicketComponent } from '../create/create-ticket.component';

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {

  constructor(public dialog: MatDialog, private ticketservice: TicketService,
    private userService: UserService) { }
  comments: any;

  ngOnInit() {
    console.log('Burda');
  }

  ticket:Ticket;
  openCreateDialog() {
    //console.log(this.selectedTicket.ticketName);
    let dialogRef = this.dialog.open(CreateTicketComponent, {
      height: '700px',
      width: '600px'
    });

    dialogRef.afterClosed().subscribe(result => {
      console.log('Burda1');
     /*  console.log("dialogRef.afterClosed => ");
      this.ticket = new Ticket(20,
     'Deneme',
     'Deneme',
     'Deneme',
     'Deneme',
     'Deneme',
      this.userService.getUser(1),
      this.userService.getUser(2),
      this.comments
    );
    this.ticketservice.accessTickets().push(this.ticket); */
    for (let entry of this.ticketservice.accessTickets()) {
      console.log(entry.ticketName);
  }
    });

  }
}

Create.component.ts

import { Component, OnInit, Inject } from '@angular/core';
import { NgForm } from '@angular/forms/src/directives/ng_form';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
import { TicketService } from '../tickets/ticket.service';
import { Ticket } from '../tickets/ticket/ticket.model';
import { User } from '../users/user.model';
import { UserService } from '../users/user.service';

@Component({
  selector: 'app-create-ticket',
  templateUrl: './create-ticket.component.html',
  styleUrls: ['./create-ticket.component.css']
})
export class CreateTicketComponent implements OnInit {

  constructor(private ticketService : TicketService,
    private userService:UserService,
    public dialogRef: MatDialogRef<CreateTicketComponent>,
    @Inject(MAT_DIALOG_DATA) public data: any
  ) { }
  ticket: Ticket;

  comments: any;
  //users: User[] = this.userService.getUsers();
  ngOnInit() {
  }

  onNoClick(): void {
    this.dialogRef.close();
  }

  OnCreate(form: NgForm) {
    const value = form.value;
    console.log('user => ' + value.itemName);
    console.log('this.ticketservice.getIdSequence() => ' + this.ticketService.getIdSequence());
    this.ticket = new Ticket(this.ticketService.getIdSequence(),
      value.itemName,
      value.itemSubject,
      value.itemDescription,
      value.itemStatus,
      value.itemType,
      this.userService.getUser(value.itemAssignee),
      this.userService.getUser(value.itemReporter),
      this.comments
    );
    console.log('user => ' + this.userService.getUser(value.itemAssignee).userFullName);
    this.ticketService.accessTickets().push(this.ticket);
    this.dialogRef.close();

    /* for (let entry of this.ticketservice.getTickets()) {
      console.log(entry.ticketName);
  } */

  }
}

Ticket service

import { Ticket } from "./ticket/ticket.model";
import { EventEmitter, Injectable } from "@angular/core";
import { Comment } from "./comments/comment.model";
import { User } from "../users/user.model";

export class TicketService {

  ticketSelected = new EventEmitter<Ticket>();


  nextSeq: number;


  private tickets: Ticket[] = [
    new Ticket(1, 'IT-1001',
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit?',
      'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris ut porta mi. Sed commodo ac enim non egestas. Morbi pellentesque sodales lacus, nec facilisis lorem commodo quis. Aenean in enim vel erat ullamcorper eleifend ac et nisi. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec risus dolor, imperdiet non sem sed, luctus rutrum quam. Vestibulum mollis pellentesque nisi, eget porta urna vehicula ac. Phasellus id nulla at purus consectetur ultricies. Ut tempus facilisis nulla eget facilisis. Donec diam magna, bibendum ac aliquet vitae, varius facilisis dui. Quisque sapien urna, gravida nec sem eleifend, sagittis vehicula dolor. Duis eu consectetur purus. Phasellus eu mi quam. Ut id leo vitae erat mollis dictum a ut leo. Proin ut efficitur sapien. Mauris interdum, turpis eget tincidunt consequat, sem lacus bibendum odio, id ultrices sem diam ut nibh.',
      'Open',
      'Task',
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      ),
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      )
      , []
    ),
    new Ticket(2, 'IT-1002',
      'Etiam velit leo, porttitor ultricies dictum quis, congue eget eros?',
      'Vestibulum suscipit, mauris in dictum sodales, massa libero dapibus mauris, in imperdiet nisl ex in lorem. Quisque commodo in tellus et placerat. Curabitur nec velit sit amet ante molestie ultrices. In nibh justo, vulputate nec vestibulum ut, vehicula id est. Sed quis lorem tristique, volutpat sapien quis, scelerisque leo. Praesent eu vulputate orci. Integer consectetur leo nibh, at dignissim nulla effi',
      'Open',
      'Task',
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      ),
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      )
      , []
    ),
    new Ticket(3, 'IT-1003',
      'Nam eget eros vulputate, luctus augue eu, tempus tortor?',
      'Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Nullam sit amet fermentum leo. Ut tempus ornare ex ut sagittis. Donec vitae lacus eget massa tristique luctus eu quis tellus. Sed ac ligula eu leo consectetur aliquam. Curabitur et dapibus lectus, in auctor massa. Nam nec tellus ac tortor malesuada rutrum. Sed aliquam ut mi sed dapibus. Donec vestibulum ultrices arcu. Vivamus vestibulum et ex non luctus.',
      'Open',
      'Task',
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      ),
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      )
      , []
    ),
    new Ticket(4, 'IT-1004',
      'Integer porttitor dignissim lacus id vestibulum?',
      'Yaygın inancın tersine, Lorem Ipsum rastgele sözcüklerden oluşmaz. Kökleri M.Ö. 45 tarihinden bu yana klasik Latin edebiyatına kadar uzanan 2000 yıllık bir geçmişi vardır. Virginiadaki Hampden-Sydney Collegedan Latince profesörü Richard McClintock, bir Lorem Ipsum pasajında geçen ve anlaşılması en güç sözcüklerden biri olan consectetur sözcüğünün klasik edebiyattaki örneklerini incelediğinde kesin bir kaynağa ulaşmıştır. Lorm Ipsum, Çiçero tarafından M.Ö. 45 tarihinde kaleme alınan "de Finibus Bonorum et Malorum" (İyi ve Kötünün Uç Sınırları) eserinin 1.10.32 ve 1.10.33 sayılı bölümlerinden gelmektedir. Bu kitap, ahlak kuramı üzerine bir tezdir ve Rönesans döneminde çok popüler olmuştur. Lorem Ipsum pasajının ilk satırı olan "Lorem ipsum dolor sit amet" 1.10.32 sayılı bölümdeki bir satırdan gelmektedir.',
      'Open',
      'Task',
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      ),
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      )
      , []
    )
    ,
    new Ticket(5, 'IT-1005',
      'Integer porttitor dignissim lacus id vestibulum?',
      'Yaygın inancın tersine, Lorem Ipsum rastgele sözcüklerden oluşmaz. Kökleri M.Ö. 45 tarihinden bu yana klasik Latin edebiyatına kadar uzanan 2000 yıllık bir geçmişi vardır. Virginiadaki Hampden-Sydney Collegedan Latince profesörü Richard McClintock, bir Lorem Ipsum pasajında geçen ve anlaşılması en güç sözcüklerden biri olan consectetur sözcüğünün klasik edebiyattaki örneklerini incelediğinde kesin bir kaynağa ulaşmıştır. Lorm Ipsum, Çiçero tarafından M.Ö. 45 tarihinde kaleme alınan "de Finibus Bonorum et Malorum" (İyi ve Kötünün Uç Sınırları) eserinin 1.10.32 ve 1.10.33 sayılı bölümlerinden gelmektedir. Bu kitap, ahlak kuramı üzerine bir tezdir ve Rönesans döneminde çok popüler olmuştur. Lorem Ipsum pasajının ilk satırı olan "Lorem ipsum dolor sit amet" 1.10.32 sayılı bölümdeki bir satırdan gelmektedir.',
      'Open',
      'Task',
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      ),
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      )
      , []
    )
    ,
    new Ticket(6, 'IT-1006',
      'Integer porttitor dignissim lacus id vestibulum?',
      'Yaygın inancın tersine, Lorem Ipsum rastgele sözcüklerden oluşmaz. Kökleri M.Ö. 45 tarihinden bu yana klasik Latin edebiyatına kadar uzanan 2000 yıllık bir geçmişi vardır. Virginiadaki Hampden-Sydney Collegedan Latince profesörü Richard McClintock, bir Lorem Ipsum pasajında geçen ve anlaşılması en güç sözcüklerden biri olan consectetur sözcüğünün klasik edebiyattaki örneklerini incelediğinde kesin bir kaynağa ulaşmıştır. Lorm Ipsum, Çiçero tarafından M.Ö. 45 tarihinde kaleme alınan "de Finibus Bonorum et Malorum" (İyi ve Kötünün Uç Sınırları) eserinin 1.10.32 ve 1.10.33 sayılı bölümlerinden gelmektedir. Bu kitap, ahlak kuramı üzerine bir tezdir ve Rönesans döneminde çok popüler olmuştur. Lorem Ipsum pasajının ilk satırı olan "Lorem ipsum dolor sit amet" 1.10.32 sayılı bölümdeki bir satırdan gelmektedir.',
      'Open',
      'Task',
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      ),
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      )
      , []
    )
    ,
    new Ticket(7, 'IT-1007',
      'Integer porttitor dignissim lacus id vestibulum?',
      'Yaygın inancın tersine, Lorem Ipsum rastgele sözcüklerden oluşmaz. Kökleri M.Ö. 45 tarihinden bu yana klasik Latin edebiyatına kadar uzanan 2000 yıllık bir geçmişi vardır. Virginiadaki Hampden-Sydney Collegedan Latince profesörü Richard McClintock, bir Lorem Ipsum pasajında geçen ve anlaşılması en güç sözcüklerden biri olan consectetur sözcüğünün klasik edebiyattaki örneklerini incelediğinde kesin bir kaynağa ulaşmıştır. Lorm Ipsum, Çiçero tarafından M.Ö. 45 tarihinde kaleme alınan "de Finibus Bonorum et Malorum" (İyi ve Kötünün Uç Sınırları) eserinin 1.10.32 ve 1.10.33 sayılı bölümlerinden gelmektedir. Bu kitap, ahlak kuramı üzerine bir tezdir ve Rönesans döneminde çok popüler olmuştur. Lorem Ipsum pasajının ilk satırı olan "Lorem ipsum dolor sit amet" 1.10.32 sayılı bölümdeki bir satırdan gelmektedir.',
      'Open',
      'Task',
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      ),
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      )
      , []
    )
    ,
    new Ticket(8, 'IT-1008',
      'Integer porttitor dignissim lacus id vestibulum?',
      'Yaygın inancın tersine, Lorem Ipsum rastgele sözcüklerden oluşmaz. Kökleri M.Ö. 45 tarihinden bu yana klasik Latin edebiyatına kadar uzanan 2000 yıllık bir geçmişi vardır. Virginiadaki Hampden-Sydney Collegedan Latince profesörü Richard McClintock, bir Lorem Ipsum pasajında geçen ve anlaşılması en güç sözcüklerden biri olan consectetur sözcüğünün klasik edebiyattaki örneklerini incelediğinde kesin bir kaynağa ulaşmıştır. Lorm Ipsum, Çiçero tarafından M.Ö. 45 tarihinde kaleme alınan "de Finibus Bonorum et Malorum" (İyi ve Kötünün Uç Sınırları) eserinin 1.10.32 ve 1.10.33 sayılı bölümlerinden gelmektedir. Bu kitap, ahlak kuramı üzerine bir tezdir ve Rönesans döneminde çok popüler olmuştur. Lorem Ipsum pasajının ilk satırı olan "Lorem ipsum dolor sit amet" 1.10.32 sayılı bölümdeki bir satırdan gelmektedir.',
      'Open',
      'Task',
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      ),
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      )
      , []
    )
    ,
    new Ticket(9, 'IT-1009',
      'Integer porttitor dignissim lacus id vestibulum?',
      'Yaygın inancın tersine, Lorem Ipsum rastgele sözcüklerden oluşmaz. Kökleri M.Ö. 45 tarihinden bu yana klasik Latin edebiyatına kadar uzanan 2000 yıllık bir geçmişi vardır. Virginiadaki Hampden-Sydney Collegedan Latince profesörü Richard McClintock, bir Lorem Ipsum pasajında geçen ve anlaşılması en güç sözcüklerden biri olan consectetur sözcüğünün klasik edebiyattaki örneklerini incelediğinde kesin bir kaynağa ulaşmıştır. Lorm Ipsum, Çiçero tarafından M.Ö. 45 tarihinde kaleme alınan "de Finibus Bonorum et Malorum" (İyi ve Kötünün Uç Sınırları) eserinin 1.10.32 ve 1.10.33 sayılı bölümlerinden gelmektedir. Bu kitap, ahlak kuramı üzerine bir tezdir ve Rönesans döneminde çok popüler olmuştur. Lorem Ipsum pasajının ilk satırı olan "Lorem ipsum dolor sit amet" 1.10.32 sayılı bölümdeki bir satırdan gelmektedir.',
      'Open',
      'Task',
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      ),
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      )
      , []
    )
    ,
    new Ticket(10, 'IT-1010',
      'Integer porttitor dignissim lacus id vestibulum?',
      'Yaygın inancın tersine, Lorem Ipsum rastgele sözcüklerden oluşmaz. Kökleri M.Ö. 45 tarihinden bu yana klasik Latin edebiyatına kadar uzanan 2000 yıllık bir geçmişi vardır. Virginiadaki Hampden-Sydney Collegedan Latince profesörü Richard McClintock, bir Lorem Ipsum pasajında geçen ve anlaşılması en güç sözcüklerden biri olan consectetur sözcüğünün klasik edebiyattaki örneklerini incelediğinde kesin bir kaynağa ulaşmıştır. Lorm Ipsum, Çiçero tarafından M.Ö. 45 tarihinde kaleme alınan "de Finibus Bonorum et Malorum" (İyi ve Kötünün Uç Sınırları) eserinin 1.10.32 ve 1.10.33 sayılı bölümlerinden gelmektedir. Bu kitap, ahlak kuramı üzerine bir tezdir ve Rönesans döneminde çok popüler olmuştur. Lorem Ipsum pasajının ilk satırı olan "Lorem ipsum dolor sit amet" 1.10.32 sayılı bölümdeki bir satırdan gelmektedir.',
      'Open',
      'Task',
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      ),
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      )
      , []
    )
    ,
    new Ticket(11, 'IT-1011',
      'Integer porttitor dignissim lacus id vestibulum?',
      'Yaygın inancın tersine, Lorem Ipsum rastgele sözcüklerden oluşmaz. Kökleri M.Ö. 45 tarihinden bu yana klasik Latin edebiyatına kadar uzanan 2000 yıllık bir geçmişi vardır. Virginiadaki Hampden-Sydney Collegedan Latince profesörü Richard McClintock, bir Lorem Ipsum pasajında geçen ve anlaşılması en güç sözcüklerden biri olan consectetur sözcüğünün klasik edebiyattaki örneklerini incelediğinde kesin bir kaynağa ulaşmıştır. Lorm Ipsum, Çiçero tarafından M.Ö. 45 tarihinde kaleme alınan "de Finibus Bonorum et Malorum" (İyi ve Kötünün Uç Sınırları) eserinin 1.10.32 ve 1.10.33 sayılı bölümlerinden gelmektedir. Bu kitap, ahlak kuramı üzerine bir tezdir ve Rönesans döneminde çok popüler olmuştur. Lorem Ipsum pasajının ilk satırı olan "Lorem ipsum dolor sit amet" 1.10.32 sayılı bölümdeki bir satırdan gelmektedir.',
      'Open',
      'Task',
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      ),
      new User(4, 'murata', 'Murat Aydın', 'murataydin@gmail.com', '1234'
      )
      , []
    )
  ];


  accessTickets() {
    return this.tickets;
  }

  getTickets() {
    return this.tickets.slice();
  }
  getIdSequence() {
    return this.nextSeq = Object.keys(this.tickets).length + 1
  }

  getTicket(ticketid: number) {
    const ticket: Ticket = this.tickets.find(
      (s) => {
        return s.ticketId == ticketid;
      }
    );
    return ticket;
  }



}

Program structure is程序结构在这里

By default Angular Material uses default root injector to create dialog.

Since you declared providers on AppComponent your dialog doesn't have access to these providers.

To fix it you could pass ViewContainerRef instance within dialog config:

export class HeaderComponent {
  constructor(public dialog: MatDialog, private vcRef: ViewContainerRef) { }

  openCreateDialog() {
    let dialogRef = this.dialog.open(CreateTicketComponent, {
      height: '700px',
      width: '600px',
      viewContainerRef: this.vcRef  <================= add this
    });
  }

In this case angular material will use config.viewContainerRef.injector instead of default:

const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;

https://github.com/angular/components/blob/master/src/material/dialog/dialog.ts#L218

Of course, another solution is providing TicketService on AppModule .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM