【问题标题】:How do I have human-readable names in the url instead of id in Angular?如何在 url 中使用人类可读的名称而不是 Angular 中的 id?
【发布时间】:2019-06-24 02:00:19
【问题描述】:

基本上,我想要的是在 url 中有人类可读的路线名称,而不是长长的 mongooseid。

例如:代替:https://localhost/campgrounds/50341373e894ad16347efe01

我要:https://localhost/campgrounds/mountain-view

其中,“mountain-view”是用户在表单字段中输入的露营地名称。

这是我的界面:

campgrounds.model.ts

export interface Campground {
_id: String;
name: String;
routeURL: String;
description: String;
cost: Number;
}

campground-create.component.html (我没有发布其他表单字段,因为这里没有必要)

<div class="container">
 <form>
  <div class="form-group">
  <label for="name">Name</label>
  <input type="text" class="form-control" id="name" name="name"
  [(ngModel)]="campground.name" (blur)="generateURL()" required>
  </div>

  <button type="submit" class="btn btn-primary" 
  (click)="addCampground()">Submit</button>
 </form>
</div>

campground-create.component.ts

这只是转换用户在表单字段中输入的露营地名称,并在调用 (blur) 时在单词之间添加连字符。

import { Component, OnInit } from '@angular/core';
import { CampgroundService } from 'src/app/campground.service';
import { Router } from '@angular/router';
import { Campground } from 'src/app/campground.model';

@Component({
selector: 'app-campground-create',
templateUrl: './campground-create.component.html',
styleUrls: ['./campground-create.component.sass']
})

export class CampgroundCreateComponent implements OnInit {

  campground: Campground = {} as Campground;

  constructor(private campgroundService: CampgroundService, private 
  router: Router) { }

  ngOnInit() {
  }

  generateURL() {
  this.campground.routeURL = this.campground.name.toLowerCase()
  .trim().split(/\s+/).join('-');
  // Retrieve campground name and add hyphens between words
  }

  addCampground() {
  this.campgroundService.addCampground(this.campground)
  .subscribe(()=> {
   this.generateURL();
   this.router.navigate(['/campground-list']);
  });
 }
}

campground-list.component.html

<div class="background">

 <header class="jumbotron jumbotron-fluid">
 <div class="container">
  <h1 class="display-4 title">Welcome to YelpCamp!</h1>
  <button type="button" [routerLink]="['/campground-create']" 
  class="btn btn-default btn-lg">Add New Campground</button>
 </div>
 </header>

 <div class="card-deck">
  <div class="card" *ngFor="let campground of campgrounds">
  <img class="card-img-top" src="{{campground?.imageURL}}" alt="Card 
  image cap">
   <div class="card-body">
    <h5 class="card-title">{{campground?.name}}</h5>
    <button type="button" routerLink="/campground- 
    details/{{campground.routeURL}}"
    class="btn btn-danger">More Info</button>
   </div>
  </div>
 </div>

</div>

但是,由于我使用“findById”,因此露营地详细信息页面不会返回来自服务的数据。

campground-routes.js

router.get('/api/campground/:id', (req, res) => {
  Campground.findById(req.params.id, (err, campground) => {
  if (err) {
  console.log(err);
  } else {
   res.json(campground);
  }
 });
});

如果我在路线中有 mongoose id,下面的方法就可以了:

campground-details.component.ts

import { Component, OnInit } from '@angular/core';
import { CampgroundService } from 'src/app/campground.service';
import { ActivatedRoute } from '@angular/router';
import { Campground } from 'src/app/campground.model';

@Component({
selector: 'app-campground-details',
templateUrl: './campground-details.component.html',
styleUrls: ['./campground-details.component.sass']
})

export class CampgroundDetailsComponent implements OnInit {

  campground: Campground;

  constructor(private campgroundService: CampgroundService, private 
  router: ActivatedRoute) {
  }

  ngOnInit() {
   this.router.params.subscribe(params => {
   const id = params['id'];

   this.campgroundService.getCampground(id).subscribe(campground=> {
   this.campground = campground;
   console.log(this.campground);
   });
  });
 }
}

有没有办法做到这一点?如果是的话,有没有简单的方法可以做到这一点?谢谢。

【问题讨论】:

  • 我还没有看到任何简单的方法来做到这一点。你确定你找不到露营地的名字吗?我对 Mongoose 不太熟悉,但我知道它可以让你定义方法——我认为findByName 方法在这里会非常有用stackoverflow.com/questions/7419969/…
  • 取而代之的是,我想知道是否可以将“id”作为查询参数传递,然后隐藏 id,同时保留名称。例如:localhost:4200/mountain-view?id=50341373e894ad16347efe01(查询参数将被隐藏)。不知道如何只隐藏 url 中的 id。
  • 有趣的想法。您需要一种方法来读取然后删除 queryParam 而不会触发新的导航事件。我会考虑的唯一其他选择是将{ campground_name: campground_id } 之类的对象数组保存在共享服务中。这样您就可以路由到/api/campground/:name,使用name 从共享服务中过滤正确的露营地,然后在getCampground() 中使用该露营地的id。开销很大,但它可能会起作用。

标签: angular mongoose angular2-routing


【解决方案1】:

您使用的是当前版本的 Angular 吗?从 Angular v7.2 开始,您可以在路由上发送 state 属性。

然后您可以发送 URL 中的名称和 state 属性中的 id。

有关使用路线的state 功能的更多信息,请参阅此链接:https://netbasal.com/set-state-object-when-navigating-in-angular-7-2-b87c5b977bb

类似这样的:

<button type="button" 
        routerLink="/campground-details/{{campground.name }}"
        [state]="{ id: campground.id }"
        class="btn btn-danger">
  More Info
</button>

【讨论】:

    猜你喜欢
    • 2011-09-04
    • 1970-01-01
    • 2017-08-20
    • 2020-09-15
    • 1970-01-01
    • 2015-03-06
    • 2014-04-09
    • 2018-06-11
    • 1970-01-01
    相关资源
    最近更新 更多