在我们的angular2 Typescript应用程序中,我们使用路由器。 我们的组件非常通用,它们的行为会根据从路由器获得的参数而发生显着变化。
该应用程序处于早期开发阶段,最近我已经观察到了我所指的行为。我不确定是否是因为代码更改或其中一个库发生了重大变化。
考虑名为List
的组件。它从上下文(路由,包装组件等)中获取一些信息,例如它应该显示的实体类型。
现在,当我更改路由时,List
组件不会重新实例化,但会更新其参数。由于我在ngOnInit
中使用这些参数来设置组件,因此后面的更改将不起作用。
我知道我可以使用变化检测来解决这个问题,但我宁愿不这样做。原因是,这将使开发人员更容易引入回归错误(例如:转到人员列表,然后执行某些操作,转到订单列表,那些不应该存在的东西),这些错误要困难得多发现,测试和复制。他们更有可能泄漏到生产中。
如何在路径更改时强制角度重新创建List组件。
更多观察:在路由器中,如果我导航到不显示List组件然后返回List的路由,则会重新实例化该组件。
答案 0 :(得分:1)
订阅活动路线参数;这是一个可观察的
答案 1 :(得分:1)
您可以使用async
管道来显示Observable的最后一个值,而不是订阅。
doc:Pipes
答案 2 :(得分:0)
当路由器导航到新路由时,它会将现有组件树与新组件树进行比较,销毁不再需要的组件,创建不存在的所需组件,以及重用任何仍需要的组件的实例。如果您使用的是同一个路径,然后从完整的url字符串手动提取suffixStuff,则angular不会注意到suffixStuff中的更改,并且不会重新创建该组件。如果你使用一个正确声明其suffixStuff的路线,那么angular会注意到它(每个Sameh的回答活动路径参数),angular会注意到并重新创建仍然需要的组件。 / p>
即便如此,这是一个需要考虑的案例。例如,List组件的oninit获取活动路由参数,并从数据库执行一次读取以设置组件。我们让用户点击该组件上的内容来创建,更新,删除数据库中的记录。因此,当这些操作完成后,我们希望从数据库重新读取以向用户显示结果(仅显示ACID数据的良好做法,不?)。我们将自然地找到我们的readAndSetup代码,该代码错误地存在于oninit方法中,并尝试某种形式的页面重新加载或重新路由,并将面临背靠背导航到相同路由(活动参数和所有)的问题将重用整个现有的组件树。
我们应该做的是将设置代码与oninit分开。 Oninit将获取活动路径参数,制作并记住来自它们的formsDbQuery,然后调用单独的this.readFromDb方法,该方法使用想起了形成的DDQuery。这样重新读取不需要重新创建组件(调用oninit),我们只需在操作完成后调用this.readFromDb。