现在用户可以登录到我们的应用程序,让我们允许他们更新他们的设置。我们需要创建一个新的页面,该页面有一个连接到UserService的update方法的表单,我们将建立一个新的页面。我们还将在这个页面的底部包含一个注销按钮,它需要调用UserService的purgeAuth方法。
创建SettingsComponent
src/app/settings/settings.component.html
<div class="settings-page"><div class="container page"><div class="row"><div class="col-md-6 offset-md-3 col-xs-12"><h1 class="text-xs-center">Your Settings</h1><list-errors [errors]="errors"></list-errors><form [formGroup]="settingsForm" (ngSubmit)="submitForm()"><fieldset [disabled]="isSubmitting"><fieldset class="form-group"><input class="form-control"type="text"placeholder="URL of profile picture"formControlName="image" /></fieldset><fieldset class="form-group"><input class="form-control form-control-lg"type="text"placeholder="Username"formControlName="username" /></fieldset><fieldset class="form-group"><textarea class="form-control form-control-lg"rows="8"placeholder="Short bio about you"formControlName="bio"></textarea></fieldset><fieldset class="form-group"><input class="form-control form-control-lg"type="email"placeholder="Email"formControlName="email" /></fieldset><fieldset class="form-group"><input class="form-control form-control-lg"type="password"placeholder="New Password"formControlName="password" /></fieldset><button class="btn btn-lg btn-primary pull-xs-right"type="submit">Update Settings</button></fieldset></form><!-- Line break for logout button --><hr /><button class="btn btn-outline-danger"(click)="logout()">Or click here to logout.</button></div></div></div></div>
这与我们在AuthComponent中的做法类似。我们本质上是在创建一个大的表单并加载现有的数据,这样我们的用户就可以更新他们的信息。现在我们只需要把它连接到UserService中的更新方法。Profile页面还不存在,但我们将在下一章创建它。
src/app/settings/settings.component.ts
import { Component, OnInit } from '@angular/core';import { FormBuilder, FormGroup } from '@angular/forms';import { Router } from '@angular/router';import { User, UserService } from '../shared';@Component({selector: 'settings-page',templateUrl: './settings.component.html'})export class SettingsComponent implements OnInit {user: User = new User();settingsForm: FormGroup;errors: Object = {};isSubmitting: boolean = false;constructor(private router: Router,private userService: UserService,private fb: FormBuilder) {// create form group using the form builderthis.settingsForm = this.fb.group({image: '',username: '',bio: '',email: '',password: ''});// Optional: subscribe to changes on the form// this.settingsForm.valueChanges.subscribe(values => this.updateUser(values));}ngOnInit() {// Make a fresh copy of the current user's object to place in editable form fields(<any>Object).assign(this.user, this.userService.getCurrentUser());// Fill the formthis.settingsForm.patchValue(this.user);}logout() {this.userService.purgeAuth();this.router.navigateByUrl('/');}submitForm() {this.isSubmitting = true;// update the modelthis.updateUser(this.settingsForm.value);this.userService.update(this.user).subscribe(updatedUser => this.router.navigateByUrl('/profile/' + updatedUser.username),err => {this.errors = err;this.isSubmitting = false;});}updateUser(values: Object) {(<any>Object).assign(this.user, values);}}
在ngOnInit()中,我们将CurrentUser的信息复制到this.user中(在这里了解更多关于assign()的信息),然后用这些值更新settingsForm。
当我们提交表单时,它会调用User Service中的一个更新函数,我们需要建立这个函数。
在用户服务中建立更新函数
src/app/shared/services/user.service.ts
[...]// Update the user on the server (email, pass, etc)update(user): Observable<User> {return this.apiService.put('/user', { user }).map(data => {// Update the currentUser observablethis.currentUserSubject.next(data.user);return data.user;});}
我们需要在ApiService中建立一个put函数来更新用户的信息。
在我们的ApiService中添加以下put()函数
[...]put(path: string, body: Object = {}): Observable<any> {return this.http.put( `${environment.api_url}${path}`, JSON.stringify(body), { headers: this.setHeaders() }).catch(this.formatErrors).map((res:Response) => res.json());}
只有已登录的用户才能访问设置页面。因此,我们将使用我们在上一章制作的AuthGuard。
创建设置模块并实现AuthGuard
src/app/settings/settings.module.ts
import { ModuleWithProviders, NgModule } from '@angular/core';import { RouterModule } from '@angular/router';import { SettingsComponent } from './settings.component';import { AuthGuard, SharedModule } from '../shared';const settingsRouting: ModuleWithProviders = RouterModule.forChild([{path: 'settings',component: SettingsComponent,canActivate: [AuthGuard]}]);@NgModule({imports: [SharedModule,settingsRouting],declarations: [SettingsComponent]})export class SettingsModule {}
最后我们需要做的是将它导入到AppModule中。
将SettingsModule导入到AppModule中。
src/app/app.module.ts
[...]import { AppComponent } from './app.component';import { AuthModule } from './auth/auth.module';import { HomeModule } from './home/home.module';+import { SettingsModule } from './settings/settings.module';import {ApiService,AuthGuard,FooterComponent,HeaderComponent,JwtService,SharedModule,UserService} from './shared';[...]BrowserModule,AuthModule,HomeModule,rootRouting,SharedModule,+ SettingsModule],providers: [ApiService,AuthGuard,JwtService,UserService],bootstrap: [AppComponent][...]
现在我们可以导航到设置页面,并更新我们的用户数据!
你可以将你的代码与Github上的有效代码进行比较,或者在本地检查分支:
git checkout m-4
