我是Angular 2和observables的新手。
我有一个带有文本框的HTML模板。当observable不返回任何数据时它会被清除,但是当数据存在时,它会被第一个数据项填充。
即使我已阅读有关可观察量的教程,我也不知道这是怎么发生的。
HTML
<form class="clearfix" role="form"
[ngFormModel]="basicDetailsForm">
<div class="form-group col-md-6 no-padding">
<label for="assignedTo" class="text-muted">Assigned To</label>
<input class="form-control bold"
id="assignedTo"
type="text"
[ngFormControl]="ctrlAssignedTo"
(change)="assignedToChanged($event)"
[(ngModel)]="activeItem.assignee.name" />
</div>
</form>
和我的组件.ts文件有
.component.ts
public ngOnInit(): void {
// subscribe to users observable
this.usersSubs = this.usersSubs || this.itemDetailService.users$.subscribe(function (user: any) {
if (user.usedFor !== 'basic') {
return;
}
if (user.id === '0') {
context.activeItem.assignee = {};
return;
}
let assignedTo: any = {
id: user.id,
type: 'user',
url: user.url,
name: user.name,
archived: false,
archiveDate: null
}
context.activeItem.assignee = assignedTo;
});
}
constructor(
@Inject(AppStateService) public appStateService: AppStateService,
@Inject(ItemDetailService) public itemDetailService: ItemDetailService,
private formBuilder: FormBuilder) {
super(appStateService, itemDetailService);
this.activeItem = this.activeItem || {
assignee: {}
};
// build the form
this.basicDetailsForm = this.formBuilder.group({
'assignedTo': ['']
});
this.ctrlAssignedTo = <Control>this.basicDetailsForm.controls['assignedTo'];
}
我的service.ts文件有
.service.ts
private usersObserver: Observer<any>;
constructor(
@Inject(ProjectsApiService) private apiService: ProjectsApiService,
@Inject(AppStateService) private appStateService: AppStateService,
@Inject(AppObservableService) private appObservableService: AppObservableService) {
this.activeDetailTab = {
index: 0
}
}
public init() {
this.users$ = this.users$ || new Observable((observer: any) => {
this.usersObserver = observer;
}).share();
}
public getUserByAlias(alias: string, usedFor: string): void {
let context = this;
this.apiService.getUserByAlias(alias)
.subscribe(
(data: any) => {
if (data.data.length === 0) {
context.usersObserver.next({ id: '0', usedFor: usedFor });
return;
}
data.data.forEach(function (user: any) {
context.users.push(user);
});
data.data[0].usedFor = usedFor;
context.usersObserver.next(data.data[0]);
},
err => { console.log(err); },
() => { console.log('Done'); }
);
}
答案 0 :(得分:3)
我会尝试按照数据流向您解释。因此,让我们从触发流程的内容开始。
你有一个输入,只要有什么变化,就会触发assignedToChanged事件。
(change)="assignedToChanged($event)"
在assignedToChanged()内部,调用服务类中的getUserByAlias()方法。
您已在上次修改中删除了此部分代码。
getUserByAlias类apiService.getUserByAlias(),这里是observables介入的地方。
首先让我们了解getUserByAlias的作用。如果您了解有关可观察对象的基础知识,则会在返回api响应时调用.subscribe。 在.subscribe里面,你将与另一个观察者打交道,我们很快就会到达那里。但是现在我要强调这里发生的三件大事。
如果api响应中没有数据,则将id为0的对象推送到userObservable流中。
if (data.data.length === 0) {
context.usersObserver.next({ id: '0', usedFor: usedFor });
return;
}
否则将填充所有用户返回的用户数组。
data.data.forEach(function (user: any) {
context.users.push(user);
});
第一个用户被推入userObserver
data.data[0].usedFor = usedFor;
context.usersObserver.next(data.data[0]);
现在,请注意上面代码段中的userObserver。此观察者是通知文本框的关键。当我们调用.next()时,我们将一个新值推送到可观察流中,因此,每个正在收听此可观察对象的人都会收到通知。
但是谁订阅了这个可观察的? 在组件内部,您正在订阅userObservable:
this.usersSubs = this.usersSubs || this.itemDetailService.users$.subscribe(function (user: any) {
//implementation removed for readbility
});
只要将新值推入可观察流( userObservable.next())
,就会始终调用.subscribe()内部的函数关键是要了解该服务正在向观察者公开任何类将能够收听,并且每当必须发送新值时,该服务将调用.next(&#39;此处为值|对象&#39;。)