請問如何切換到一個全新的空白頁面?

我在寫一個網站。
這個網站有三個 components
一個是首頁(app.component)。首頁裡面有兩個按鈕,登入與註冊。
一個是登入 (login.component)
一個是註冊(register.component)
在首頁點擊「註冊」按鈕的時候,畫面會切換到一個全新的畫面(就是不要出現app.component,也不要出現 login.component)
請問在 Angular 要如何實現?我試驗好久都試驗不出來。
謝謝幫忙

你有使用路由嗎?

Hi,
謝謝回覆。
我有使用 Router ,但不確定用法是否正確。我再描述詳細一點我的需求:

  1. 構想:因為註冊的頁面的 layout 與首頁(app.component)不一樣。且註冊的頁面會需要全版空間顯示其他的資訊,以及他自己的 banner。

  2. 實做:因為也只有註冊頁面是特例。因此,我的想法,會是希望像一般非SPA 網站一樣,在點擊「註冊」後,換到一個新的頁面,在新的頁面裡,register.component.html 可以自己隨意設計,這樣比較不會干擾到其他的版型,也不會使版型變得太複雜。所以,我想要的Angular的行為是:

    2.1 用戶點擊「註冊」
    2.2 Angular 把 app.component.html 關閉
    2.3 Angular 把 register.component.html 打開,並且使用全版空間(整個頁面)
    2.4 當用戶按下「取消註冊」時,Angular 關閉 register.componrnt.html, 再開啟 app.component.html
    2.5 當用戶按下「完成註冊」時,Angular 對 API Server 發送註冊資訊。API Server 回覆註冊成功時,Angular 把 register.component.html 關閉,然後開啟 app.component.html

以上,是我的想法。還請給予指導。
感恩

我貼一下我相關的程式碼

app.module.ts

import { BrowserModule }    from '@angular/platform-browser';
import { NgModule }        from '@angular/core';
import { HttpClientModule}      from '@angular/common/http';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent }       from './app.component';
import { jqxGridModule }      from 'jqwidgets-ng/jqxgrid';
import { jqxWindowModule }    from 'jqwidgets-ng/jqxwindow';
import { jqxInputModule }     from 'jqwidgets-ng/jqxinput';
import { jqxPasswordInputModule }  from  'jqwidgets-ng/jqxpasswordinput';
import { jqxButtonModule }    from 'jqwidgets-ng/jqxbuttons';
import { jqxNotificationModule} from 'jqwidgets-ng/jqxnotification';
import { jqxLoaderModule} from 'jqwidgets-ng/jqxloader';
import { RegisterComponent } from './register/register.component';

const appRoutes: Routes = [
  {path: 'register', component: RegisterComponent}
]

@NgModule({
  declarations: [ AppComponent, RegisterComponent ],
  imports: [
    RouterModule.forRoot(
      appRoutes,
      {enableTracing: true}   // <-- debugging purposes obnly
    ),
    BrowserModule, HttpClientModule,
    jqxGridModule, jqxWindowModule, jqxInputModule,
    jqxPasswordInputModule, jqxButtonModule, jqxNotificationModule,
    jqxLoaderModule
  ],
  bootstrap: [ AppComponent ]
})

export class AppModule { }

=================================================
app.component.html

<div id="banner">
  <a [routerLink]="['/']" linkActive>
  <div id="site_name_title">
    ABCDEFGHI
  </div>
  </a>
  <div id="user_info_area">
    <div *ngIf="loginUser == null; else else_block">
      <div class="emulate_button float_right" >
        <a routerLink="/register" routerLinkActive="active">註&nbsp;&nbsp;冊</a>
      </div>
      <div class="separator_slash float_right"> / </div>
      <div class="emulate_button float_right" (click)="openLoginWindow()">登&nbsp;&nbsp;入</div>
    </div>
    <ng-template #else_block>
      <div class="emulate_button float_right" (click)="doLogout()" >登出系統</div>

      <div class="float_right margin_top_5px">
        {{loginUser.fullName}}, &nbsp;
      </div>
    </ng-template>
  </div>
</div>
<router-outlet></router-outlet>

<jqxWindow #loginWindow
     [theme]="'material-purple'" [width]="400" [height]="300"
           [autoOpen]="false" [isModal]="true"
>
  <div>登&nbsp;&nbsp;入</div>

  <div>
    <div  style="text-align: center">
      <br/>
      <div class="margin_top_5px">
      <jqxInput #loginEmail
                [placeHolder]="'請輸入 Email'" [theme]="global.getJqxTheme()" [width]="300"

      >
      </jqxInput>
      </div>
      <div class="margin_top_5px">
      <jqxPasswordInput #loginPassword
                        [placeHolder]="'請輸入密碼'" [theme]="global.getJqxTheme()"
                        [width]="300"
      ></jqxPasswordInput>
      </div>
      <div class="margin_top_5px">
      <jqxButton [theme]="global.getJqxTheme()" (click)="doLogin()">登&nbsp;&nbsp;入</jqxButton>&nbsp;&nbsp;
      <jqxButton [theme]="global.getJqxTheme()" (click)="doCancelLogin()">取&nbsp;&nbsp;消</jqxButton>
      </div>
    </div>
    <hr style="width:310px;"/>


  </div>
</jqxWindow>

<jqxNotification  #mainNotification [theme]="'bootstrap'" [width]="'auto'" [height]="'auto'" [opacity]="1.0">
  <div id="mainNotifyMessage" class="font18"></div>
</jqxNotification>

<jqxLoader #loader>

</jqxLoader>

========================================================
app.component.ts

import { AfterViewInit, Component, ViewChild} from '@angular/core';
import { jqxWindowComponent} from 'jqwidgets-ng/jqxwindow';
import { jqxInputComponent} from 'jqwidgets-ng/jqxinput';
import { jqxPasswordInputComponent} from 'jqwidgets-ng/jqxpasswordinput';
import { jqxButtonComponent} from 'jqwidgets-ng/jqxbuttons';
import { jqxNotificationComponent} from 'jqwidgets-ng/jqxnotification';
import { jqxLoaderComponent} from 'jqwidgets-ng/jqxloader';
import { Global} from './utils/Global';
import { AuthService} from './service/auth.service';
import { HttpErrorResponse} from '@angular/common/http';
import {NotificationService} from './service/notification.service';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [Global]
})

export class AppComponent implements  AfterViewInit {
  loginUser: any = null;
  @ViewChild('loginWindow', {static: false}) loginWindow: jqxWindowComponent;
  @ViewChild('loginEmail', {static: false}) loginEmail: jqxInputComponent;
  @ViewChild('loginPassword', {static: false}) loginPassword: jqxPasswordInputComponent;
  @ViewChild('mainNotification', {static: false}) mainNotification: jqxNotificationComponent;
  @ViewChild('loader', {static: false}) loader: jqxLoaderComponent;
 
  constructor(
    private global: Global,
    private authService: AuthService,
    private notificationService: NotificationService
    ) {
    if (localStorage.getItem(Global.LOGIN_RESPONSE) != null) {
      const tmp = localStorage.getItem(Global.LOGIN_RESPONSE);
      this.loginUser = JSON.parse(tmp);
      console.log('loginUser:' + this.loginUser.username);
    }
  }
  ngAfterViewInit(): void {
    // this.initJqxWidgets();
    this.notificationService.initContainer(this.mainNotification);
  }
  initJqxWidgets(): void {

  }

  openLoginWindow(): void {
    this.loginWindow.open();
  }

  doCancelLogin() {
    this.loginWindow.close();
  }
  doLogin() {
    console.log('loginEmail:' + this.loginEmail.val());
    const loginResult = this.authService.login(
      this.loginEmail.val(),
      this.loginPassword.val()
    );
    this.loginWindow.close();
    this.loader.text('登入中....');
    console.log('start subscribe.....');
    loginResult.subscribe(
      (loginResult2: any) => {
        // this.loader.close();
        console.log('doLogin(): loginResult2:' + JSON.stringify(loginResult2, null, 2));
        this.authService.saveTokenInfo(loginResult2);
        this.loginUser = loginResult2;
      },
      (err: HttpErrorResponse) => {
        // this.loader.close();
        if (err.error instanceof Error) {
          // A client-side or network error occurred. Handle it accordingly.
          console.log('An error occurred:', err.error.message);
        } else {
          // The backend returned an unsuccessful response code.
          // The response body may contain clues as to what went wrong,
          console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
          this.notificationService.notifyMessage('帳號或密碼錯誤', 'error', 0);
        }
      },
      () => {
        console.log('complete....');
        this.loader.close();
      }
    );
  }

  doLogout() {
    this.loginUser = null;
    this.authService.clearLoginResponse();
    this.notificationService.notifyMessage('登出系統完成', 'info', 4);
  }
  getJqxTheme() {
    // console.log("GlobalConst.THEME=" + GlobalConst.THEME);
    return Global._THEME;
  }
}

============================================
register.component.html

<p>
  <div>Banner </div>
  register works!
</p>

===========================================
register.component.ts

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

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

  constructor() { }

  ngOnInit() {
  }

}

基本上使用 Route 設定就可以完成了

const appRoutes: Routes = [
  {path: 'register', component: RegisterComponent},
  {path:'', component: LayoutComponent, children: 
      [
         {path: '', component: HomeComponent},
          ...
      ]}
]

可以透過這種方式來將 Layout 做區隔,不同網址可以擁有不同的 layout 設定, 透過 router.navigate 的方式做網址切換即可

@wureka 關於路由的設置,可以參考我去年鐵人賽的文章,裡面就有提到怎麼切換不同版型的頁面。

1個讚

感謝,花了些時間,有點瞭解了。