我在寫一個網站。
這個網站有三個 components
一個是首頁(app.component)。首頁裡面有兩個按鈕,登入與註冊。
一個是登入 (login.component)
一個是註冊(register.component)
在首頁點擊「註冊」按鈕的時候,畫面會切換到一個全新的畫面(就是不要出現app.component,也不要出現 login.component)
請問在 Angular 要如何實現?我試驗好久都試驗不出來。
謝謝幫忙
你有使用路由嗎?
Hi,
謝謝回覆。
我有使用 Router ,但不確定用法是否正確。我再描述詳細一點我的需求:
-
構想:因為註冊的頁面的 layout 與首頁(app.component)不一樣。且註冊的頁面會需要全版空間顯示其他的資訊,以及他自己的 banner。
-
實做:因為也只有註冊頁面是特例。因此,我的想法,會是希望像一般非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">註 冊</a>
</div>
<div class="separator_slash float_right"> / </div>
<div class="emulate_button float_right" (click)="openLoginWindow()">登 入</div>
</div>
<ng-template #else_block>
<div class="emulate_button float_right" (click)="doLogout()" >登出系統</div>
<div class="float_right margin_top_5px">
{{loginUser.fullName}},
</div>
</ng-template>
</div>
</div>
<router-outlet></router-outlet>
<jqxWindow #loginWindow
[theme]="'material-purple'" [width]="400" [height]="300"
[autoOpen]="false" [isModal]="true"
>
<div>登 入</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()">登 入</jqxButton>
<jqxButton [theme]="global.getJqxTheme()" (click)="doCancelLogin()">取 消</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 的方式做網址切換即可
感謝,花了些時間,有點瞭解了。