【问题标题】:Understanding observables in angular 2理解角度 2 中的 observables
【发布时间】:2016-07-11 12:03:46
【问题描述】:

我是 Angular 2 和 observables 的新手。

我有一个带有文本框的 HTML 模板。当 observables 没有返回任何数据时它会被清除,但是当数据存在时它会被第一个数据项填充。

我不知道这是怎么发生的,尽管我已经阅读了有关 observables 的教程。

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

【问题讨论】:

  • 请提供订阅用户观察者的代码部分。这样我就可以准确地告诉你发生了什么。
  • @DanielPliscki 更新了代码。请查看
  • 我没有找到任何订阅 userObserver 。我唯一想到的是 observable.share()
  • 您提到一个文本框正在填充结果。提供 HTML 和控制它的组件部分。此外,包括组件和服务的构造函数。
  • @DanielPliscki 谢谢你帮助我。按照您的要求更新了代码。

标签: javascript angular rxjs observable


【解决方案1】:

我将尝试按照数据流向您解释。那么让我们从触发流程的因素开始。

您有一个 Input,它会在发生变化时触发 assignmentToChanged 事件。

(change)="assignedToChanged($event)"

在assignedToChanged() 中调用了服务类中的getUserByAlias() 方法。

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

getUserByAlias 类 apiService.getUserByAlias(),这是 observables 介入的地方。

首先让我们了解 getUserByAlias 的作用。如果您了解有关 observables 的基础知识,您就会知道 .subscribe 在返回 api 响应时被调用。 在 .subscribe 中,您将处理另一个 observable,我们很快就会到达那里。但现在我将重点介绍这里发生的三件主要事情。

如果 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]);

现在,请注意上面 sn-ps 中的 userObserver。这个观察者是通知文本框的关键。当我们调用 .next() 时,我们将一个新值推送到 observable 流中,因此,正在监听这个 observable 的每个人都会收到通知。

但是谁订阅了这个 observable? 在组件内部,您正在订阅 userObservable:

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

每当一个新值被推入可观察流(userObservable.next()

时,都会调用 .subscribe() 中的函数

关键点是要理解服务公开了一个观察者,任何类都可以监听,并且每当必须发送新值时,服务将调用 .next('here go the value|object' )。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-23
    • 2016-10-09
    • 2023-03-26
    • 2017-03-07
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多