Я новичок в Angular2, и я пытаюсь выяснить шаблон проектирования для родительских и дочерних компонентов для выполнения действий при изменении атрибута в службе, эта услуга доступна глобально (объявлена в app.component.ts
в атрибуте providers
). Я использую:Angular2 наблюдать за атрибутом в службе для изменений
- Угловые 2,2,1
- rxjs 5.0.0-beta.12
- машинопись 2.2.1
В основном услуга подключается к удаленному API, и этот API требует аутентификации маркера. Служба имеет общедоступные функции login()
и logout()
. Первый обращается к API, а затем устанавливает частный атрибут token
в строку токена (если действует логин) или '' (если недействительный логин). Все остальные публичные функции, которые вызывают вызовы API, используют этот закрытый токен.
Я предположил, что нет необходимости в компонентах, которые используют эту услугу, для просмотра или использования атрибута токена, поскольку они должны быть «глупыми» для бизнес-процессов API и только потреблять данные через это оказание услуг.
Сервис (упрощенный)
import { Injectable } from '@angular/core';
import { Http, Response, Headers, URLSearchParams } from '@angular/http';
import {Observable, Subject} from 'rxjs/Rx';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
@Injectable()
export class ApiService {
private url:string = 'my.service.com/';
private username: string;
private password: string;
private token: string;
constructor (private http: Http) {}
public getUsername(): string {
return this.username;
}
public setUsername(username: string) {
this.username = username;
}
public getPassword(): string {
return this.password;
}
public setPassword(password: string) {
this.password = password;
}
private setToken(token: string) {
this.token = token;
}
public login() {
let headers = new Headers({ 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' });
let urlSearchParams = new URLSearchParams();
urlSearchParams.append('username', this.username);
urlSearchParams.append('password', this.password);
let body = urlSearchParams.toString();
let url = this.url + 'user/login';
this.http.post(url, body, {headers: headers})
.map(res => {this.setToken(typeof res['token'] !== 'undefined' ? res['token'] : '');});
}
public logout() {
this.setToken('');
}
public getData() {
let headers = new Headers({ 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' });
let urlSearchParams = new URLSearchParams();
urlSearchParams.append('token', this.token);
let body = urlSearchParams.toString();
let url = this.url + 'data';
return this.http.get(url, body, {headers: headers})
.map(res => res.json());
}
app.component.ts
import { Component, ViewEncapsulation } from '@angular/core';
import { ApiService } from './services/api';
@Component({
selector: 'app',
encapsulation: ViewEncapsulation.None,
styleUrls: ['./app.component.global.scss'],
templateUrl: './app.component.html',
providers: [ApiService]
})
export class AppComponent {
constructor(private apiService: ApiService) {}
}
ребенок компонент
import { Component } from '@angular/core';
import { ApiService } from '../services/api';
@Component({
selector: 'child-component',
styleUrls: ['./child-component.component.scss'],
templateUrl: './child-component.component.html'
})
export class ChildComponent {
data: any[];
constructor(private apiService: ApiService) {}
}
Как Я получаю компоненты (например, ChildComponent
для наблюдения за состоянием частного атрибута token
в ApiService
, а когда это не '', вызывать функции в сервисе, для которых требуется токен (например, getData()
)? Возможно, я приближаюсь к этому не так, но мои причины для его приближения состоят в том, что существует несколько дочерних компонентов, зависящих от действительного токена, для извлечения/отправки и отображения данных, а также только для получения/отправки данных при успешном входе в систему Я экспериментировал с различными ngOnChanges, Observerable, Subject.emit и т. Д., Но не смог выполнить эту работу.
Спасибо за ответ Йохан, это аккуратное решение, но не совсем соответствует моим требованиям. Я хотел, чтобы страница всегда была доступна, но некоторые дочерние компоненты на странице должны заполняться только тогда, когда пользователь вошел в систему. Я детализирую решение, с которым я столкнулся ниже. Но я обновляю ваш ответ как полезный. – vim
Извините, я не могу повышать это, у меня есть rep <15. Но было записано. – vim