【问题标题】:Resolver does not resolve if another data stream is added如果添加了另一个数据流,解析器不会解析
【发布时间】:2018-07-12 13:07:38
【问题描述】:

我正在尝试使用解析器来根据路由保存的给定参数检索数据。

不幸的是,当我添加另一个我的数据依赖于解析器的数据流时,我从未真正解析过。

如果我直接返回一个立即解析的值,一切正常。 我调试了情况,看到我收到了所有的部分信息,但最终还是没有真正解决。

这是一个快速示例。如果需要更多代码来理解问题,请联系我。

我的服务:

export class MyService {
  get(bar) {
    return of(new Foo(bar));
  }
}

SecondService(这个从后端检索数据):

export class SecondService {
  private readonly _observable: Observable<Bar>;
  constructor() {
    this._observable = merge(
      // Other manipulations
    ).pipe(
      // other manipulations
      shareReplay(1)
    )
  }

  observable(): Observable<Bar> {
    return this._observable;
  }
}

解析器:

export class MyResolver {
  constructor(_secondService: SecondService, _myService: MyService) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Foo> {
    // Does not work - Simply does not resolve
    // return this._secondService
    //   .observable()
    //   .pipe(
    //     switchMap((bar) => this._myService.get(bar)),
    //   );

    // WORKS
    return of(new Foobar('sampleData'));
  }
}

路由器:

const routes: Routes = [
  {
    path: 'someroute',
    component: SomeComponent,
    canActivate: [SomeGuard],
    resolve: {
      myData: MyResolver,
    },
  },
];

组件:

export class SomeComponent implements OnInit {
  constructor(private readonly _route: ActivatedRoute) {}

  ngOnInit() {
    this._route.data
      .subscribe((data) => {
      console.log('received:', data);
      this.myData = data;      
    });
  }
}

SomeComponent.html

<pre *ngIf="myData">
  Received: {{ myData | json }}
</pre>

【问题讨论】:

    标签: angular angular6 angular-router angular-resolver


    【解决方案1】:

    我的问题的答案相当简单,与订阅已解析的 observables 无关,因为框架已经自动完成了。

    为了完成解析器,它所依赖的所有流都需要complete。如果您碰巧使用了 hot observable,则需要使用另一个运算符,例如 take,以便流在该位置完成。

    所以,所有代码都保持不变,除了我将解析器更改为:

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Foo> {
      return this._secondService
        .observable()
        .pipe(
          take(1),
          switchMap((bar) => this._myService.get(bar)),
      );
    }
    

    @eduPeeth:感谢您的回答/建议,不幸的是,这是一个小得多的问题。

    【讨论】:

    • 解析器遇到了同样的问题。解析器只是挂起,直到流结束。同样,我使用的是return this.do().pipe(first());,它需要takefirst 或任何结束流的东西才能解决。
    【解决方案2】:

    Observable 只有在你显式调用 Observable.subscribe() 时才会被执行。我在您的代码中没有看到您订阅 Observables 的任何地方。

    注意:resolve 的概念与 Promise 相关,与 Observable 无关。

    试试:

    export class MyResolver {
      constructor(_secondService: SecondService, _myService: MyService) {}
    
      resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Foo> {
        // Does not work - Simply does not resolve
         return this._secondService
           .observable()
           .pipe(
             take(1),
             switchMap((bar) => this._myService.get(bar)),
           }     
           );
    
        // WORKS
        return of(new Foobar('sampleData')).pipe(
             take(1),
             switchMap((bar) => this._myService.get(bar)),          
         });
      }
    }
    

    在您需要结果的地方订阅。

    【讨论】:

    • 没错,我没有在任何给定的 observables 上明确调用 .subscribe()。我认为这是通过角度神奇地完成的,因为文档没有在任何地方说明它(angular.io/guide/router#route-definition-with-a-parameter)。如果有的话,我会在目标组件中订阅路由器的数据,以检索已解析的给定数据。我将相关组件添加到我的初始帖子中。
    • 您需要在您期望从 Observable 返回值的某个或其他地方订阅每个 Observable。请考虑一下您的要求并尝试订阅。尝试更新代码,如果仍然遇到问题,请帮助您。
    • 我不知道如何添加您的建议。如果 angular 本身确实实例化了解析器并将数据进一步传递给组件,我将如何 subscribe() 到我的自定义解析器。如问题所述,数据实际上是流动的,解析器最终没有解析。
    • 添加了一些代码 sn -p 试试看你有没有得到结果?
    • 如我自己的回答中所述,导致问题的原因是缺少 take() 执行。最后,我已经在我的组件中订阅了已解析的 Observable。这也是我需要结果的地方,因此在解析器中订阅会使我再次遇到同样的问题 - 我的组件中没有数据。无论如何,感谢您的时间、建议和帮助!
    猜你喜欢
    • 2021-02-26
    • 2017-12-11
    • 2023-03-22
    • 2020-08-02
    • 1970-01-01
    • 1970-01-01
    • 2013-12-15
    • 2016-12-13
    • 2018-05-13
    相关资源
    最近更新 更多