当前位置:  开发笔记 > 编程语言 > 正文

使用Observables,在延迟后显示加载指示,但如果加载及时完成则取消?

如何解决《使用Observables,在延迟后显示加载指示,但如果加载及时完成则取消?》经验,为你挑选了1个好方法。

在我的客户详细信息组件中,我有以下代码可以实现我所追求的目标,但不是我认为可能的反应/可观察方式.

而不是包装this.isLoading = true;在if语句中,有没有办法使用反应式编程技术?如果首先检索客户,可能通过取消/删除延迟的可观察量?或者,我是否采取了错误的方式?

export class CustomerDetailComponent implements OnInit {

  customer: Customer;
  errorMessage: string;
  isLoading: boolean;

  constructor(
    private customerService: CustomerService,
    private route: ActivatedRoute,
    private router: Router,
    private location: Location
  ) { }

  ngOnInit() { 
    let idParam = this.route.params
      .distinctUntilChanged(params => params['id']);

    idParam.subscribe(params => 
    {
      this.errorMessage = ''; 
    });

    idParam.delay(300).subscribe(params => 
    {
      if (!(this.customer && this.customer.id == params['id']))
        this.isLoading = true;
    });

    idParam.switchMap((params: Params) => this.customerService.getCustomer(params['id']))
      .subscribe(customer => 
      { 
        this.customer = customer; 
        this.isLoading = false;
      },
      error => this.errorMessage = error);
  }
}

martin.. 6

你可以按照以下方式写一些东西:

function getCustomer(id) {
    return Observable.of({'name': 'John', id}).delay(500);
}

Observable.of({'id': 42})
    .distinctUntilChanged(params => params['id'])
    .do(() => {
        // this.errorMessage = '';
    })
    .switchMap((params) => {
        return Observable.combineLatest(
            Observable.of(true).delay(300).startWith(null), // delay Observable
            getCustomer(params['id']).startWith(null), // customer Observable
            function(delay, customer) { // selector function
                if (customer) {
                    return customer;
                }

                if (delay && !customer) {
                    console.log('this.isLoading = true;');
                }
                return null;
            })
            .filter(customer => customer)
            .distinctUntilChanged(customer => customer['id']);
    })
    .subscribe(
        customer => {
            console.log('this.isLoading = false;');
            console.log(customer);
            // this.customer = customer;
        },
        error => {
            // this.errorMessage = error;
        }
    );

观看现场演示:https://jsbin.com/nebutup/5/edit?js,console

内部combineLatest()接收两个Observable:

    300毫秒的延迟

    来自远程服务的客户(在此演示模拟中)

然后还有投影函数用于选择我们想要进一步传播的内容.两个Observable都使用它.startWith(null)来确保它们至少有一个项目被释放,因此它们combineLatest()将由任何一个项目的变化触发.然后我们可以很容易地知道发出的第一个Observable是延迟还是客户.

然后还要filter()删除所有null值并distinctUntilChanged()确保我们不会两次发出相同的客户(这处理客户首先完成的情况).

然后,当我们运行此演示并且首先触发延迟时,输出如下:

this.isLoading = true;
this.isLoading = false;
{ name: 'John', id: 42 }

这意味着我们首先显示加载然后隐藏它.

然后当我们改变getCustomer()先完成时:

function getCustomer(id) {
    return Observable.of({'name': 'John', id}).delay(100);
}

我们将得到以下内容:

this.isLoading = false;
{ name: 'John', id: 42 }

这意味着我们从不显示任何负载.



1> martin..:

你可以按照以下方式写一些东西:

function getCustomer(id) {
    return Observable.of({'name': 'John', id}).delay(500);
}

Observable.of({'id': 42})
    .distinctUntilChanged(params => params['id'])
    .do(() => {
        // this.errorMessage = '';
    })
    .switchMap((params) => {
        return Observable.combineLatest(
            Observable.of(true).delay(300).startWith(null), // delay Observable
            getCustomer(params['id']).startWith(null), // customer Observable
            function(delay, customer) { // selector function
                if (customer) {
                    return customer;
                }

                if (delay && !customer) {
                    console.log('this.isLoading = true;');
                }
                return null;
            })
            .filter(customer => customer)
            .distinctUntilChanged(customer => customer['id']);
    })
    .subscribe(
        customer => {
            console.log('this.isLoading = false;');
            console.log(customer);
            // this.customer = customer;
        },
        error => {
            // this.errorMessage = error;
        }
    );

观看现场演示:https://jsbin.com/nebutup/5/edit?js,console

内部combineLatest()接收两个Observable:

    300毫秒的延迟

    来自远程服务的客户(在此演示模拟中)

然后还有投影函数用于选择我们想要进一步传播的内容.两个Observable都使用它.startWith(null)来确保它们至少有一个项目被释放,因此它们combineLatest()将由任何一个项目的变化触发.然后我们可以很容易地知道发出的第一个Observable是延迟还是客户.

然后还要filter()删除所有null值并distinctUntilChanged()确保我们不会两次发出相同的客户(这处理客户首先完成的情况).

然后,当我们运行此演示并且首先触发延迟时,输出如下:

this.isLoading = true;
this.isLoading = false;
{ name: 'John', id: 42 }

这意味着我们首先显示加载然后隐藏它.

然后当我们改变getCustomer()先完成时:

function getCustomer(id) {
    return Observable.of({'name': 'John', id}).delay(100);
}

我们将得到以下内容:

this.isLoading = false;
{ name: 'John', id: 42 }

这意味着我们从不显示任何负载.

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有