理解角度2中的可观察量

时间:2016-07-11 12:03:46

标签: javascript angular rxjs observable

我是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'); }
                );
        }

1 个答案:

答案 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;。)