• 第一个 Angular 项目 - 添加路由


    第一个 Angular 项目 - 添加路由

    前置项目是 第一个 Angular 项目 - 添加服务,之前的切换页面使用的是 ngIf 对渲染的组件进行判断,从而完成渲染。这一步的打算是添加路由,同时添加 edit recipe 的功能(同样通过路由实现)

    用到的内容为:


    配置基础路由

    这里修改的文件有以下文件:

    在这里插入图片描述

    其中:

    • header
    • recipe-details
    • recipe-item

    三个 HTML Template 修改的内容为删除 a 标签中的 href 属性,并添加 style="cursor: pointer" 维持原本的样式,这里不多赘述

    其他修改如下:

    • app-routing

      const appRoutes: Routes = [
        { path: '', redirectTo: '/recipes', pathMatch: 'full' },
        { path: 'recipes', component: RecipesComponent },
        { path: 'shopping-list', component: ShoppingListComponent },
      ];
      
      @NgModule({
        imports: [RouterModule.forRoot(appRoutes)],
        exports: [RouterModule],
      })
      export class AppRoutingModule {}
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      这里主要的修改在 routing 两篇笔记中都提过,最低层次的配置需求需要包含路径和对应的组件,redirectTo 中使用 pathMatch 因为 Angular 的路由是通过前缀匹配的,如果不添加这个属性,那么从首页登陆就会 infinite loop,从而报错

    • app V 层

      删除原本的 ngIf 部分,替换为

    • app module

      imports 中新增 AppRoutingModule

    实现后效果如下:

    在这里插入图片描述

    添加子路由

    设置如下:

    const appRoutes: Routes = [
      {
        path: 'recipes',
        component: RecipesComponent,
        children: [
          { path: '', component: RecipeStartComponent },
          { path: 'new', component: RecipeEditComponent },
          { path: ':id', component: RecipeDetailComponent },
          { path: ':id/edit', component: RecipeEditComponent },
        ],
      },
    ];
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    实现后效果如下:

    在这里插入图片描述

    这里基本上没什么特别难的,唯一需要注意的就是 :idnew 的顺序。:id 也算是一个 wildcard,它会将所有的参数都默认为变量名为 id 的值,并且传到 Params 里去

    修改获取 recipe

    这里是 recipe details 的实现,修改如下:

    export class RecipeDetailComponent implements OnInit {
      recipeId: string;
      activeRecipe: Recipe;
    
      constructor(
        private ingredientService: IngredientService,
        private recipeService: RecipeService,
        private activatedRouter: ActivatedRoute
      ) {}
    
      ngOnInit(): void {
        this.activatedRouter.params.subscribe((params: Params) => {
          this.recipeId = params.id;
          this.activeRecipe = this.recipeService.getRecipeById(this.recipeId);
        });
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    service 中的实现就是返回 array 中的数据就是了,这里实现不多赘述

    其他需要做的地方就是 recipe-list 中传值的 onSelect,以及对应的数据传输(@Input & @Output)

    动态拼接路由

    当前项目还是一个 dummy 项目,所以没法做到直接从 recipe 中获取 id,所以这里要做的就是从 ngFor 中将 index 传到下一个组件,并且在下一个组件中获取 id:

    • recipe list 修改:

      <app-recipe-item
        *ngFor="let recipe of recipes; let i = index"
        [recipe]="recipe"
        [id]="i + 1"
      >app-recipe-item>
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • recipe item 修改:

      <a
        style="cursor: pointer"
        [routerLink]="[id]"
        routerLinkActive="active"
        class="list-group-item clearfix"
      >a>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    对应的 @Input 绑定就不实现了,这部分内容在 [Angular 基础] - 自定义事件 & 自定义属性 中;ngFor 的复习在 [Angular 基础] - 指令(directives)

    此时的实现如下:

    在这里插入图片描述

    可以看到和之前的实现基本没有变化,除了 URL 路径的变动

    edit recipe 实现

    具体的功能会等到学完表单再实现,不过这里通过 ngOnInit 简单的判断一下当前页面是新建页面还是编辑页面:

    @Component({
      selector: 'app-recipe-edit',
      templateUrl: './recipe-edit.component.html',
      styleUrl: './recipe-edit.component.css',
    })
    export class RecipeEditComponent implements OnInit {
      id: number;
      editMode = false;
    
      constructor(private route: ActivatedRoute) {}
    
      ngOnInit() {
        this.route.params.subscribe((params: Params) => {
          this.id = +params.id;
          this.editMode = isNaN(this.id);
        });
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    这里的逻辑处理相对而言比较暴力,简单的说就是如果传进来的参数不是 new——有 new 走不进 :id——并且无法转成数字,那么就肯定不是编辑模式,这种情况下默认转为新建模式。

    具体的逻辑处理可以写很细,这里只是大致实现一下

    new 和 edit 的路由实现

    这个部分比较简单,Angular 似乎对 routerLink 得绑定没什么限制,注意一下绝对路径/相对路径就能实现了:

    在这里插入图片描述

    ⚠️:另一个实现方式是绑定 onclick handler,随后通过 this.router.navigate 进行实现。二者都可以,鉴于现在并没有什么复杂的逻辑需求,我就直接绑定 routerLink

  • 相关阅读:
    json读写
    Zookeeper实现分布式锁的原理。
    Webrtc MCU SFU模式OWTServer Docker快速运行
    【第十七篇】商城系统-购物车功能设计
    数组的拷贝和反转和扩容与缩减
    《2023中国企业数智化转型升级服务全景图/产业图谱2.0版》重磅发布
    【C++】LeetCode 160 相交链表
    背包问题详解(含代码)
    HTML知识点
    ChatGPT付费创作系统V2.4.9独立版 +WEB端+ H5端 + 小程序端系统测试安装教程
  • 原文地址:https://blog.csdn.net/weixin_42938619/article/details/136494518