Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 观测服务-误读/最佳实践_Angular_Observable_Angular Event Emitter - Fatal编程技术网

Angular 观测服务-误读/最佳实践

Angular 观测服务-误读/最佳实践,angular,observable,angular-event-emitter,Angular,Observable,Angular Event Emitter,我正在努力解决两个组件之间的观察服务方法。我有一个配置文件组件,其中包括一个设置组件。两者都使用user.service,其中提供程序在app.module.ts中定义。在其他任何地方都没有定义提供程序。因此,当我更改settings.component上的firstName作为示例并保存它时。在我重新加载页面之前,更改不会反映在profile.component侧边栏中 下班后: 我找到了一个解决方案,可以通过一个eventemitter实现这一点,它将在更新发生时立即触发。这将解决我上面的问

我正在努力解决两个组件之间的观察服务方法。我有一个配置文件组件,其中包括一个设置组件。两者都使用user.service,其中提供程序在app.module.ts中定义。在其他任何地方都没有定义提供程序。因此,当我更改settings.component上的firstName作为示例并保存它时。在我重新加载页面之前,更改不会反映在profile.component侧边栏中

下班后: 我找到了一个解决方案,可以通过一个eventemitter实现这一点,它将在更新发生时立即触发。这将解决我上面的问题,但我认为这不是正确的方法,因为我读了下面的文章:

如果没有活动主持人,它不应该工作吗

那么我的问题是: 在这种情况下,您会采用什么方法,或者最佳做法是什么?当然,我的代码中可能存在问题。我是个新手

应用程序模块.ts

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

export class ProfileComponent implements OnInit {
    user: any;
    Role = Role;
    constructor(private _userService: UserService, ) { }


    ngOnInit() {
        const token = localStorage.getItem('token');
        const role = jwt.decode(token).user.role;
        this._userService.getUser().subscribe(v => { this.user = v; });
        // Event Emmiter Subscription
        this._userService.change.subscribe(v => { this.user = v; });
    }
}
@Injectable()
export class UserService {
    public user: any;

    constructor(private http: Http) { }
    // EVENT EMIITER
    public change: EventEmitter<any> = new EventEmitter();
    getUser() {
        const token = localStorage.getItem('token')
            ? '?token=' + localStorage.getItem('token')
            : '';
        return this.http.get('api/user' + token)
            .map((response: Response) => {
                this.user = response.json().obj;
                return this.user;
            })
            .catch((error: Response) => Observable.throw(error.json()));
    }

    updateUser(user) {
        const body = JSON.stringify(user);
        const headers = new Headers({'Content-Type': 'application/json'});
        const token = localStorage.getItem('token')
            ? '?token=' + localStorage.getItem('token')
            : '';
        return this.http.patch('api/user/' + token, body, {headers: headers})
            .map((response: Response) => {
                const result = response.json();
                this.user = result.obj;
                // EMIT EVENT
                this.change.emit(this.user);
                return this.user;
            })
            .catch((error: Response) => Observable.throw(error.json()));
    }
}
ngOnInit() {
    this._userService.getUser().subscribe((user: User) => {
        this.user = user;         
    });
}

onSubmit() {
    this._userService.updateUser(this.user)
        .subscribe(
            data => {
                this._toastyService.default('Settings saved!');
                console.log(data);
            },
            error =>{
                this._toastyService.default('Error occured!');
                console.log(error);
            }
        );
}
在我定义的app.module.ts中:

 providers: [UserService]
profile.component.ts

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

export class ProfileComponent implements OnInit {
    user: any;
    Role = Role;
    constructor(private _userService: UserService, ) { }


    ngOnInit() {
        const token = localStorage.getItem('token');
        const role = jwt.decode(token).user.role;
        this._userService.getUser().subscribe(v => { this.user = v; });
        // Event Emmiter Subscription
        this._userService.change.subscribe(v => { this.user = v; });
    }
}
@Injectable()
export class UserService {
    public user: any;

    constructor(private http: Http) { }
    // EVENT EMIITER
    public change: EventEmitter<any> = new EventEmitter();
    getUser() {
        const token = localStorage.getItem('token')
            ? '?token=' + localStorage.getItem('token')
            : '';
        return this.http.get('api/user' + token)
            .map((response: Response) => {
                this.user = response.json().obj;
                return this.user;
            })
            .catch((error: Response) => Observable.throw(error.json()));
    }

    updateUser(user) {
        const body = JSON.stringify(user);
        const headers = new Headers({'Content-Type': 'application/json'});
        const token = localStorage.getItem('token')
            ? '?token=' + localStorage.getItem('token')
            : '';
        return this.http.patch('api/user/' + token, body, {headers: headers})
            .map((response: Response) => {
                const result = response.json();
                this.user = result.obj;
                // EMIT EVENT
                this.change.emit(this.user);
                return this.user;
            })
            .catch((error: Response) => Observable.throw(error.json()));
    }
}
ngOnInit() {
    this._userService.getUser().subscribe((user: User) => {
        this.user = user;         
    });
}

onSubmit() {
    this._userService.updateUser(this.user)
        .subscribe(
            data => {
                this._toastyService.default('Settings saved!');
                console.log(data);
            },
            error =>{
                this._toastyService.default('Error occured!');
                console.log(error);
            }
        );
}
profile.component.html

<div *ngIf="user" class="container mt50">
    <div class="row profile">
        <div class="col-md-3">
            <div class="profile-sidebar">
                <!-- SIDEBAR USERPIC -->
                <div class="profile-userpic">
                    <img gravatar [email]="user.email" [size]="256" class="img-responsive animated bounceIn" alt="">
                </div>
                <!-- END SIDEBAR USERPIC -->
                <!-- SIDEBAR USER TITLE -->
                <div class="profile-usertitle">
                    <div class="profile-usertitle-name">
                        {{ user.firstName }} {{ user.lastName }}
                    </div>
                    <div class="profile-usertitle-job">
                        {{ user.email }}
                    </div>
                </div>
            </div>
        </div>
        <div class="col-md-9">
                <app-profile-settings-admin *ngIf="user.role === Role.ADMINISTRATOR"></app-profile-settings-admin>
        </div>
    </div>
</div>
<form #userForm="ngForm">
    <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" id="name" aria-describedby="nameHelp" 
            placeholder="enter name" [(ngModel)]="user.name" name="name" required #name="ngModel">
        <div [hidden]="name.valid || name.pristine"
            class="alert alert-danger">
            Name is required
        </div>
    </div>
     <div class="form-group">
        <label for="lastName">Last Name</label>
        <input type="text" class="form-control" id="lastName" aria-describedby="lastNameHelp" 
            placeholder="enter last name" [(ngModel)]="user.lastName" name="lastName" required #lastName="ngModel">
        <div [hidden]="lastName.valid || lastName.pristine"
            class="alert alert-danger">
            last Name is required
        </div>
    </div>
    <div class="form-group">
        <label for="email">Email</label>
        <input type="email" class="form-control" id="email" aria-describedby="emailHelp" 
            placeholder="enter email" [(ngModel)]="user.email" name="email" required #email="ngModel">
        <div [hidden]="email.valid || email.pristine"
            class="alert alert-danger">
            email is required
        </div>
    </div>

    <button type="submit" class="btn btn-success" (click)="onSubmit()" >Submit</button>
</form>
无需触发事件即可在组件之间共享(和同步)数据。让角度服务(和角度窗体)为您控制:

Profile.component

ngOnInit() {
    const token = localStorage.getItem('token');
    const role = jwt.decodeToken(token).user.role;
    this._userService.getUser().subscribe(v => {
        this.user = v; 
    });
}
用户服务

getUser() {
    const token = localStorage.getItem('token')
        ? '?token=' + localStorage.getItem('token')
        : '';
    return this.http.get('api/user' + token)
        .pipe(map((user: HttpResponse<any>) => {
            this.user = user;
                return this.user;
            }),
        catchError((error: HttpErrorResponse) => Observable.throw(error)))
}

updateUser(user) {
    const body = JSON.stringify(user);
    const headers: HttpHeaders =  new HttpHeaders({'Content-Type': 'application/json'});
    const token = localStorage.getItem('token')
        ? '?token=' + localStorage.getItem('token')
        : '';
    return this.http.patch('api/user/' + token, body, {headers})
        .pipe(map((user: HttpResponse<any>) => {
            this.user = user;
            return this.user;
        }),
        catchError((error: HttpErrorResponse) => Observable.throw(error)));
}
profile.settings.admin.component.html

<div *ngIf="user" class="container mt50">
    <div class="row profile">
        <div class="col-md-3">
            <div class="profile-sidebar">
                <!-- SIDEBAR USERPIC -->
                <div class="profile-userpic">
                    <img gravatar [email]="user.email" [size]="256" class="img-responsive animated bounceIn" alt="">
                </div>
                <!-- END SIDEBAR USERPIC -->
                <!-- SIDEBAR USER TITLE -->
                <div class="profile-usertitle">
                    <div class="profile-usertitle-name">
                        {{ user.firstName }} {{ user.lastName }}
                    </div>
                    <div class="profile-usertitle-job">
                        {{ user.email }}
                    </div>
                </div>
            </div>
        </div>
        <div class="col-md-9">
                <app-profile-settings-admin *ngIf="user.role === Role.ADMINISTRATOR"></app-profile-settings-admin>
        </div>
    </div>
</div>
<form #userForm="ngForm">
    <div class="form-group">
        <label for="name">Name</label>
        <input type="text" class="form-control" id="name" aria-describedby="nameHelp" 
            placeholder="enter name" [(ngModel)]="user.name" name="name" required #name="ngModel">
        <div [hidden]="name.valid || name.pristine"
            class="alert alert-danger">
            Name is required
        </div>
    </div>
     <div class="form-group">
        <label for="lastName">Last Name</label>
        <input type="text" class="form-control" id="lastName" aria-describedby="lastNameHelp" 
            placeholder="enter last name" [(ngModel)]="user.lastName" name="lastName" required #lastName="ngModel">
        <div [hidden]="lastName.valid || lastName.pristine"
            class="alert alert-danger">
            last Name is required
        </div>
    </div>
    <div class="form-group">
        <label for="email">Email</label>
        <input type="email" class="form-control" id="email" aria-describedby="emailHelp" 
            placeholder="enter email" [(ngModel)]="user.email" name="email" required #email="ngModel">
        <div [hidden]="email.valid || email.pristine"
            class="alert alert-danger">
            email is required
        </div>
    </div>

    <button type="submit" class="btn btn-success" (click)="onSubmit()" >Submit</button>
</form>

名称
名称是必需的
姓
姓是必需的
电子邮件
电子邮件是必需的
提交

最好的做法是不要为此使用EventEmitter,链接问题对此进行了解释。改用RxJS主题。