直接访问孩子时如何管理路由中的数据?

时间:2019-05-21 11:46:29

标签: angular angular-routing

以其中有一个展示品牌汽车的angular 7应用程序为例。这是我们的组件以及括号中的相应路由路径:

  • BrandListComponent/brands)将列出所有可用品牌。当您点击某个品牌时,它会将您重定向到其详细信息。
  • BrandDetailComponent/brands/:brandId)会向您显示品牌信息以及用于访问品牌汽车列表的按钮。
  • CarListComponent/brands/:brandId/cars)将显示所选品牌的所有汽车,并为您提供获取特定汽车信息的可能性。 您没有汽车的ID,只有它的名字。
  • CarSummaryComponent/brands/:brandId/cars/:carName)显示所选汽车的摘要。它需要具有brandIdcarName才能从API调用数据:/brands/42/cars?filter[name]=mx5

如果我们以用户的导航来访问我们的网站,则网址将按以下顺序排列:

  1. /brands
  2. /brands/42
  3. /brands/42/cars
  4. /brands/42/cars/mx5/summary

仅当您知道mx5用于品牌42(因为名称mx5也可能在另一个品牌中)并且此行为是故意的时,您才能获取mx5的数据。 / p>

现在想像一下,用户不想总是走这4个步骤来获取自己的汽车摘要,并将/brands/42/cars/mx5/summary添加到他的收藏夹中。

当他访问它时,我们需要检索carName(mx5)的当前参数,这很容易,因为它来自我们当前的路线,所以:

export class CarSummaryComponent implements OnInit {

  constructor(private route: ActivatedRoute) { }

  ngOnInit() {
    console.log(this.route.snapshot.params); // {carName: 'mx5'}
  }

}

但是,如何在不将CarSummaryComponent和他的父路径this.route.snapshot.parent.parent.params耦合的情况下获得brandId?

我尝试依赖queryParams中的RouterLink,但是我发现在我的案例中使用它是不切实际的,因为它添加了URL中已经具有的参数,因此您可以复制信息:{ {1}}

所以我正在寻找最佳的等待时间,以便在整个路由过程中递归地获取信息集。我看到当您直接访问/brands/42/cars/mx5?brandId=42时,它仍然执行每个父级的构造函数,因此也许解决方案从这里开始,但是实例化存储参数的服务对我来说不是一个明智的选择,有人对此进行了解释正确地:https://github.com/angular/angular/issues/10248#issuecomment-312660931

目前,这是我解决问题的全过程:

  • 以某种方式利用路由的解析器系统(此时正在获取有关它的知识)。顺便说一下,我可能会需要它来验证所需的输入(因为我使用路由来替代@Input)。
  • 依靠.../summary的新状态(但是如何通过编程方式设置它而不执行Navigation()吗?)

我想创建“纯”组件,就像我使用@ Input / @ Output一样,但依赖于路由中的数据。甚至更好的是,我可能会尝试从找到的解决方案中创建自己的装饰器,以使其像带有RouterLink的纯组件。

如果您有其他/更好的解决方案,我将很乐意倾听他们的声音!

也感谢您抽出宝贵的时间来帮助:)

编辑:这是我目前实现的解决方案,但是我无法直接在装饰器内部进行依赖项注入,因此我们需要在构造器内部声明@RouteInput() brandId: number;名称正确({{1)}。

第二个问题,类型应始终为字符串,但是您不能从装饰器中推断出它,因此如果有人写ActivatedRoute 该应用程序在运行时而不是编译时崩溃。

最后但并非最不重要的一点是,性能可能会成为一个真正的问题,因为它会为每个route重写ngOnInit并创建一个新的函数调用,并且对于每个carName: {name: string}也会遍历整个不变的路线

这是初稿,但有效:

@RouteInput

1 个答案:

答案 0 :(得分:0)

我使用参数来捕获URL的参数

我为您举例说明如何使用它,为您服务。

csv_file<-read.csv("~/Documents/FileA.csv")

csv_file.s <- ddply(csv_file, .(Bloodtype), transform, rescale = scale(Count))

csv_file.s$Category <- csv_file.s$Bloodtype

levels(csv_file.s$Category) <- 
  list("Opos" = c("Opos"),
       "Apos" = c("Apos"),
       "Bpos" = c("Bpos"),
       "ABpos" = c("ABpos"),
       "Oneg" = c("Oneg"),
       "Aneg" = c("Aneg"),
       "Bneg" = c("Bneg"),
       "Oneg" = c("Oneg"),
       "Unknown" = c("Unknown"))

csv_file.s$rescaleoffset <- csv_file.s$rescale + 100*(as.numeric(as.factor(csv_file.s$Category))-1)
scalerange <- range(csv_file.s$rescale)
gradientends <- scalerange + rep(c(0,100,200), each=8)
colorends <- c("white", "Aquamarine4", "white", "yellow4", "white", "turquoise4","white","orange4", "white", "slategray4","white","seagreen4","white","purple4","white","red4","white","blue4")


ggplot(csv_file.s, aes(Bloodtype, Animal)) + 
  geom_tile(aes(fill = rescaleoffset), colour = "transparent") + 
  scale_fill_gradientn(colours = colorends, 
                       values = rescale(gradientends)) + 
  scale_x_discrete("", expand = c(0, 0))+ 
  scale_y_discrete("", expand = c(0, 0)) +
  theme(panel.background = element_rect(fill = 'white'))
  theme_grey(base_size = 12) + 
  theme(legend.position = "none",
        axis.ticks = element_blank(), 
        axis.text.x = element_text(angle = 330, hjust = 0))