我们正在尝试构建一个“配置文件”页面,其中包含打开“模态”窗口以编辑相同用户信息的选项。我们正在使用 Angular 4 / TypeScript / Firebase / AngularFire2 。我们在主屏幕上看到了用户的个人资料数据,但它没有显示为"值"当模态窗口启动时输入字段(见图)。
显示的值(涂黑)显示但尝试编辑时数据不同。
Firebase节点内容示例(节点:/ users)
注意:这是从Internet浏览器复制的,以获取/ users节点的记录结构的副本。
kGAMmM5PYvMemxYrXcjaH3gOOYB4
address: "1234 Fake Street"
businessLinkCode: ""
city: "Faketown"
email: "john@smith.com"
modifiedDate: "2017-07-25"
modifiedTime: "1:20:33 pm"
name: "John Smith"
phone: "1234567890"
photoUrl: "https://firebasestorage.googleapis.com/v0/b/tow..."
position: "Assistant"
state_: "North Fake State"
zipCode: "12345"
组件TS(缩写):
import { Component, OnInit } from '@angular/core';
import { PageTitleService } from '../../core/page-title/page-title.service';
import {fadeInAnimation} from '../../core/route-animation/route.animation';
import {NgbModal, ModalDismissReasons} from '@ng-bootstrap/ng-bootstrap';
import { AngularFireDatabase, FirebaseObjectObservable, FirebaseListObservable } from 'angularfire2/database';
import {FormControl, Validators} from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import * as firebase from 'firebase/app';
import { AuthService } from '../../services/auth.service';
...
export class UserProfileComponent implements OnInit {
user: FirebaseObjectObservable<any>;
...
constructor(
private authService: AuthService,
private db: AngularFireDatabase,
private userService: UserService,
private pageTitleService: PageTitleService,
private modalService: NgbModal
) {
this.users = db.list('/users');
}
...
ngOnInit() {
this.pageTitleService.setTitle('User Profile');
this.authService.user$.subscribe((user) => {
this.user = this.userService.getUser(user.uid)
});
}
...
// MODAL
open(content) {
this.authService.user$.subscribe((user) => {
this.user = this.userService.getUser(user.uid)
});
this.modalService.open(content).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
HTML
<div fxLayoutWrap="wrap" fxLayoutAlign="start">
<div fxFlex.gt-md="100" fxFlex.gt-sm="100" fxFlex="100">
<div class="user-content">
<md-card id="profile">
<div fxLayoutWrap="wrap" fxLayoutAlign="start" class="user-profile">
<div class="user-contact-info">
<button style="background-color: #004380; color: white; height: 45px; width: 45px; min-width: 0; padding: 1.5%; border-radius: 50%;" (click)="open(editProfilePicture)" md-raised-button class="mrgn-b-md"><md-icon>image</md-icon></button>
<div class="perfect-circle" style="height: 240px; width: 240px; margin: 0 auto; padding-top: 0%;">
<img class="img-responsive img-circle" [src]="(user | async)?.profile_imageUrl" alt="{{ (user | async)?.name }}" title="{{ (user | async)?.name }}">
</div>
<div class="contact-list">
<h2 style="text-align: center">{{ (user | async)?.name }}</h2>
<p style="font-weight: light; font-size: medium; text-align: center"> {{ (user | async)?.position }}</p>
<button style="background-color: #004380; color: white; margin-bottom: 10%;" (click)="open(editProfile)" md-raised-button class="mrgn-b-md">EDIT PROFILE</button>
<p><i class="fa fa-envelope mat-text-primary" aria-hidden="true"></i> <strong>E-mail:</strong><a href="mailto:{{ (user | async)?.email }}"> {{ (user | async)?.email }}</a></p>
<p><i class="fa fa-phone mat-text-primary" aria-hidden="true"></i> <strong>Phone:</strong><a href="tel:{{ (user | async)?.phone }}"> {{ (user | async)?.phone }}</a></p>
<p><i class="fa fa-map-marker mat-text-primary" aria-hidden="true"></i> <strong> Address:</strong><span> {{ (user | async)?.address }}</span></p>
<p><i class="fa fa fa-map mat-text-primary" aria-hidden="true"></i> <strong>City:</strong><span> {{ (user | async)?.city }}</span></p>
<p><i class="fa fa fa-globe mat-text-primary" aria-hidden="true"></i> <strong>State:</strong><span> {{ (user | async)?.state_ }}</span></p>
</div>
</div>
<ng-template #editProfile let-c="close" let-d="dismiss">
<div>
<div class="modal-header">
<h4 class="modal-title">Edit Profile</h4>
<button style="background-color: transparent; border: none; cursor: pointer;" type="button" class="close" aria-label="Close" (click)="d('Cross click')">
<i style="font-size: large; color: gray" class="fa fa fa-times" aria-hidden="true"></i>
</button>
</div>
<form #form="ngForm" (ngSubmit)="submit(editUser)" class="form">
<md-input-container class="full-width">
<input mdInput placeholder="First and Last Name" type="text" required [(ngModel)]="editUser.name" [formControl]="nameFormControl">
</md-input-container>
<div class="flex-layout">
<md-input-container class="half-width">
<input mdInput placeholder="Position/Title" type="text" name="position" [(ngModel)]="editUser.position" [formControl]="positionFormControl">
</md-input-container>
<md-input-container class="half-width">
<span mdPrefix>+1 </span>
<input mdInput placeholder="Phone" #phone maxlength="10" type="tel" name="phone" required [(ngModel)]="editUser.phone" [formControl]="phoneFormControl">
<md-hint align="end">{{phone.value.length}} / 10</md-hint>
</md-input-container>
</div>
<md-input-container class="full-width">
<input mdInput placeholder="Address" type="text" name="address" required [(ngModel)]="editUser.address" [formControl]="addressFormControl">
</md-input-container>
<div class="flex-layout">
<md-input-container class="third-width">
<input mdInput placeholder="City" type="text" name="city" required [(ngModel)]="editUser.city" [formControl]="cityFormControl">
</md-input-container>
<md-input-container class="third-width">
<input mdInput placeholder="State" type="text" name="state" required [(ngModel)]="editUser.state_" [formControl]="state_FormControl">
</md-input-container>
<md-input-container class="third-width">
<input mdInput placeholder="Zipcode" #zipcode maxlength="5" name="zipCode" required [(ngModel)]="editUser.zipCode" [formControl]="zipCodeFormControl">
<md-hint align="end">{{zipcode.value.length}} / 5</md-hint>
</md-input-container>
</div>
<br>
<button style="background-color: #004380; color: white;" md-raised-button [disabled]="!form.valid" (click)="submit(user) + c('Close click')" class="mrgn-b-md">SAVE ACCOUNT</button>
<button style="background-color: gray; color: white;" md-raised-button type="button" class="mrgn-b-md" (click)="c('Close click')">CANCEL</button>
</form>
</div>
</ng-template>
<ng-template #editProfilePicture let-c="close" let-d="dismiss">
<div>
<div class="modal-header">
<h4 class="modal-title">Edit Profile Picture</h4>
<button style="background-color: transparent; border: none; cursor: pointer;" type="button" class="close" aria-label="Close" (click)="d('Cross click')">
<i style="font-size: large; color: gray" class="fa fa fa-times" aria-hidden="true"></i>
</button>
</div>
<img class="img-responsive" [src]="(user | async)?.profile_imageUrl" alt="{{ (user | async)?.name }}" title="{{ (user | async)?.name }}">
<form #form="ngForm" (ngSubmit)="submit(user)" class="form">
<br>
<input type="file" name="image" class="inputfile form-control" required value="upload" (change)="filebuttoni($event)"/>
<br>
<button style="background-color: #004380; color: white;" md-raised-button [disabled]="!form.valid" (click)="submit(user) + c('Close click')" class="mrgn-b-md">SAVE IMAGE</button>
<button style="background-color: gray; color: white;" md-raised-button type="button" class="mrgn-b-md" (click)="c('Close click')">CANCEL</button>
</form>
</div>
</ng-template>
</div>
</md-card>
</div>
</div>
答案 0 :(得分:0)
问题结果是ngModel应用于输入元素的方式。在这个时候,我还没有深入到Angular来解释原因,但它确实有效并且允许我继续前进。
无效的代码:
<input mdInput placeholder="First and Last Name" type="text" required [(ngModel)]="editUser.name" [formControl]="nameFormControl">
有效的代码:
<input mdInput placeholder="First and Last Name" type="text" name="name" required [ngModel]="(editUser | async)?.name" [formControl]="nameFormControl">
正如你所看到的那样[(ngModel)]被切换到[ngModel]并且我将数据绑定属性重写为“(editUser | async)?. name”,这使得它与显示相同字段的方式一致用于展示时。
表格代码替换:
<form #form="ngForm" (ngSubmit)="updateUser(editUser)" class="form">
<md-input-container class="full-width">
<input mdInput placeholder="First and Last Name" type="text" name="name" required [ngModel]="(editUser | async)?.name" [formControl]="nameFormControl">
</md-input-container>
<div class="flex-layout">
<md-input-container class="half-width">
<input mdInput placeholder="Position/Title" type="text" name="position" [ngModel]="(editUser | async)?.position" [formControl]="positionFormControl">
</md-input-container>
<md-input-container class="half-width">
<span mdPrefix>+1 </span>
<input mdInput placeholder="Phone" #phone maxlength="15" type="tel" name="phone" required [ngModel]="(editUser | async)?.phone" [formControl]="phoneFormControl">
<md-hint align="end">{{phone.value.length}} / 15</md-hint>
</md-input-container>
</div>
<md-input-container class="full-width">
<input mdInput placeholder="Address" type="text" name="address" required [ngModel]="(editUser | async)?.address" [formControl]="addressFormControl">
</md-input-container>
<div class="flex-layout">
<md-input-container class="third-width">
<input mdInput placeholder="City" type="text" name="city" required [ngModel]="(editUser | async)?.city" [formControl]="cityFormControl">
</md-input-container>
<md-input-container class="third-width">
<input mdInput placeholder="State" type="text" name="state" required [ngModel]="(editUser | async)?.state_" [formControl]="state_FormControl">
</md-input-container>
<md-input-container class="third-width">
<input mdInput placeholder="Zipcode" #zipcode maxlength="5" name="zipCode" required [ngModel]="(editUser | async)?.zipCode" [formControl]="zipCodeFormControl">
<md-hint align="end">{{zipcode.value.length}} / 5</md-hint>
</md-input-container>
</div>
<br>
<button style="background-color: #004380; color: white;" md-raised-button [disabled]="!form.valid" type="submit" class="mrgn-b-md">SAVE ACCOUNT</button>
<button style="background-color: gray; color: white;" md-raised-button type="button" class="mrgn-b-md" (click)="c('Close click')">CANCEL</button>
</form>