Angular this.router 即使在构造函数中声明也是未定义的

Angular this.router is undefined even declared in the constructor

正如你在我的 angular 项目中看到的那样,我正在构造函数中输入路由器,就像我在几年前做过的几个项目中所做的那样,我忘记了很多事情,重点是不是将我重定向到 /home 并且 this.router 未定义。

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'login',
  templateUrl: './login.component.html',
  styleUrls:['./login.component.css']
})
export class LoginComponent implements OnInit {
  
  constructor( private router: Router) { }

  ngOnInit(): void {
  }

  login(username : string, password: string): void {
    console.log(username);
    console.log(this.router);
    this.router.navigate(['/home']);
  }
}

我已经看到很多 post 错误是路由器没有在构造函数中被感染,但在我的情况下是这样。

这也是我的app.module.ts

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

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginBoxComponent } from './components/loginBox/loginbox.component';
import { HomeComponent } from './pages/home/home.component';
import { LoginComponent } from './pages/login/login.component';
import { MainComponent } from './pages/main/main.component';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent,
    LoginBoxComponent,
    LoginComponent,
    HomeComponent,
    MainComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule,
    FormsModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

应用-routing.module.ts

import { LoginComponent } from './pages/login/login.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './pages/home/home.component';
import { MainComponent } from './pages/main/main.component';

const routes : Routes = [
  {path: 'home', component: HomeComponent},
  {path: 'login', component: LoginComponent},
  {path: '**', pathMatch: 'full', redirectTo: '/login'}
]

@NgModule({
  declarations: [],
  imports: [
    RouterModule.forRoot(routes)
  ],
  exports: [
    RouterModule
  ]
})
export class AppRoutingModule { }

以及涉及的组件/页面 login.component.html

<div class="text-center" style="width: 100%">
    <loginbox [clickLoginFunction]="login"></loginbox>
</div>

loginboc.component.html

<div class="wrapper fadeInDown">
  <div id="formContent" >

    <!--
    <div class="fadeIn first">
      <img src="http://danielzawadzki.com/codepen/01/icon.svg" id="icon" alt="User Icon" />
    </div>
    -->
    <div class="m-3">
      <h1>WigStat</h1>
      <form>
        <div class="mt-3">
          <input type="text" [(ngModel)]="emailOrUsername" id="login" class="fadeIn second" name="emailOrUsername" placeholder="username">
        </div>
        <div class="mt-3">
          <input type="password" [(ngModel)]="password" id="password" class="fadeIn third" name="password" placeholder="password">
        </div>
        <div class="mt-3">
          <input type="submit" class="fadeIn fourth mt-4 mb-4" value="Log In" (click)="loginClick()">
        </div>
      </form>
    </div>

    <!--
    <div id="formFooter">
      <a class="underlineHover" href="#">Forgot Password?</a>
    </div>
    -->

  </div>
</div>

loginboc.component.ts

import { Component, Input, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import Swal from 'sweetalert2';

@Component({
  selector: 'loginbox',
  templateUrl: './loginbox.component.html',
  styleUrls:['./loginbox.component.css']
})
export class LoginBoxComponent implements OnInit {
  
  @Input()
  clickLoginFunction!: (emailOrUsername: string, password: string) => void;
  
  emailOrUsername!: string;;
  password!: string;

  constructor() {
   }
  
  ngOnInit(): void {
  }

  loginClick(){
    console.log("Internal function call in component");
    
    if(this.emailOrUsername === undefined || this.emailOrUsername === ''){
      this.showErrorModelInRegister('No se han introducido usuario');
      return;
    } else if (this.password === undefined || this.password === ''){
      this.showErrorModelInRegister('No se ha introducido password');
      return;
    }
    this.clickLoginFunction(this.emailOrUsername, this.password);
  }

  private showErrorModelInRegister(message:string){
    Swal.fire(message);
  }
}

“这个”变量的控制台日志

正如您在日志中看到的,我可以看到用户名已被完美接收

有谁知道发生了什么事吗?

提前致谢

解决方案:使用@Output。我使用 @Input 是错误的,因为信息从 child 到 parent。

loginbox.component.ts

import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
import { Router } from '@angular/router';
import Swal from 'sweetalert2';

@Component({
  selector: 'loginbox',
  templateUrl: './loginbox.component.html',
  styleUrls:['./loginbox.component.css']
})
export class LoginBoxComponent implements OnInit {

  @Output() clickLoginFunction!: EventEmitter<loginArguments>;
  
  emailOrUsername!: string;;
  password!: string;

  constructor() {
    this.clickLoginFunction = new EventEmitter();
  }
  
  ngOnInit(): void {
  }

  loginClick(){
    console.log("Internal function call in component");
    
    if(this.emailOrUsername === undefined || this.emailOrUsername === ''){
      this.showErrorModelInRegister('No se han introducido usuario');
      return;
    } else if (this.password === undefined || this.password === ''){
      this.showErrorModelInRegister('No se ha introducido password');
      return;
    }
    let loginParam:loginArguments={emailOrUsername: this.emailOrUsername, password: this.password}; 
    this.clickLoginFunction.emit(loginParam);
  }

  private showErrorModelInRegister(message:string){
    Swal.fire(message);
  }
}

export interface loginArguments{
  emailOrUsername:string,
  password:string
}

login.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { loginArguments } from 'src/app/components/loginBox/loginbox.component';

@Component({
  selector: 'login',
  templateUrl: './login.component.html',
  styleUrls:['./login.component.css']
})
export class LoginComponent implements OnInit {
  
  constructor( private router: Router) { 
    console.log("Contructor of login component called")
  }

  ngOnInit(): void {
  }

  login(loginParameter : loginArguments): void {
    console.log(loginParameter.emailOrUsername);
    console.log(loginParameter.password);
    this.router.navigate(['/home']);
  }
}

login.component.html

<div class="text-center" style="width: 100%">
    <loginbox (clickLoginFunction)="login($event)"></loginbox>
</div>

谢谢@A.Chiesa!