3

在我们的 angular2 Typescript 应用程序中,我们使用路由器。我们的组件非常通用,它们的行为会根据从路由器获得的参数而发生巨大变化。

该应用程序处于早期开发阶段,我所指的行为最近已被观察到。我不确定这是因为代码更改还是其中一个库发生了重大更改。

考虑一个名为 的组件List。它从上下文(路由、包装组件等)中获取一些信息,例如它应该显示的实体类型。

现在,当我更改路线时,List不会重新实例化组件,但会更新其参数。由于我使用这些参数ngOnInit来设置组件,因此以后的更改将无效。

我知道我可以使用变更检测来解决这个问题,但我宁愿不这样做。原因是这将使开发人员更容易引入回归错误(例如:转到人员列表,然后做某事,转到订单列表,不应该存在的东西),而这些错误更难发现,测试和重现。它们更有可能泄漏到生产中。

当路由发生变化时,如何强制 Angular 重新创建 List 组件。

更多观察:在路由器中,如果我导航到不显示 List 组件的路由,然后返回 List,则重新实例化该组件。

4

3 回答 3

1

订阅活动路由参数;这是一个可观察的

于 2016-10-18T15:01:16.590 回答
1

async您可以使用管道显示 Observable 的最后一个值,而不是订阅。

文档:管道

于 2016-10-21T16:37:38.800 回答
0

当 Router 导航到新路由时,它将现有的组件树与新的组件树进行比较,销毁不再需要的组件,创建不存在的需要的组件,并重用任何仍然需要的组件的实例。如果您使用的是一模一样的路由,然后从完整的 url 字符串中手动提取 suffixStuff,则 Angular 不会注意到 suffixStuff 的变化,也不会重新创建组件。如果您使用正确声明其 suffixStuff 的路由,以便 angular 会注意到它(根据 Sameh 的回答是一个活动的路由参数),则 angular 会注意到并重新创建仍然需要的组件。

即便如此,这里有一个需要考虑的案例。例如,List 组件的 oninit 获取活动路由参数并从数据库执行一次读取以设置组件。我们让用户点击那个组件上的东西来创建、更新、删除数据库中的记录。因此,当这些操作完成后,我们希望重新读取数据库以向用户显示结果(最好只显示 ACID 数据,不是吗?)。我们自然会找到错误地存在于 oninit 方法中的 readAndSetup 代码,并尝试某种形式的页面重新加载或重新路由,并且将面临背靠背导航到相同路由(活动参数和所有)的问题重用整个现有的组件树。

我们应该做的是将设置代码与 oninit 分开。Oninit 将获取活动路由参数,从中创建并记住一个formedDbQuery,然后调用一个单独的this.readFromDb 方法,该方法使用记住的formedDbQuery。这样重读不需要重新创建组件(调用 oninit),我们只需在操作完成后调用 this.readFromDb。

于 2017-11-12T14:49:13.980 回答