了解角度 2 中的可观察量

Understanding observables in angular 2

本文关键字:观察 了解      更新时间:2023-09-26

我是Angular 2和可观察量的新手。

我有一个带有文本框的 HTML 模板。当可观察量不返回任何数据时,它会被清除,但当数据存在时,它会用第一个数据项填充。

我不知道这是怎么发生的,即使我已经阅读了有关可观察量的教程。

.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'];
    }

和我的服务.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'); }
                );
        }

我将尝试按照数据流向您解释它。因此,让我们从触发流的原因开始。

您有一个输入,每当发生更改时,它都会触发 assigned ToChanged 事件。

(change)="assignedToChanged($event)"

在 assignedToChanged() 中,有一个对服务类中 getUserByAlias() 方法的调用。

您已在上次编辑中删除了这部分代码。

getUserByAlias class apiService.getUserByAlias() 这就是可观察量介入的地方。

首先,让我们了解 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);
});

第一个用户被推入用户观察者

data.data[0].usedFor = usedFor;
context.usersObserver.next(data.data[0]);

现在,请注意上述代码片段中的用户观察者。此观察器是通知文本框的关键。当我们调用 .next() 时,我们将一个新值推送到可观察流中,因此,每个正在侦听此可观察量的人都会收到通知。

但是谁订阅了这个可观察量?在组件内部,您正在订阅 userObservable:

this.usersSubs = this.usersSubs || this.itemDetailService.users$.subscribe(function (user: any) {
  //implementation removed for readbility
});

每当将新值推入可观察流(userObservable.next() )时,将始终调用 .subscribe() 中的函数

关键点是要了解服务正在公开一个观察者,任何类都能够侦听该观察器,并且每当必须发送新值时,服务将调用 .next('here goes the value|object')。