Angular как сохранить идентификатор пользователя в разных представлениях

#angular

#angular

Вопрос:

У меня есть таблица, завернутая в форму в Angular, что я хочу иметь возможность сделать, так это: пользователь нажимает на выбранный продукт, с которым связан id_number, этот id_number должен быть доступен для всех представлений после его выбора, поскольку api получает информацию на основе этого номера? Лучше ли создать сервис для этого? затем внедрить этот сервис в каждое представление? Код для таблицы:

HTML:

     <form [formGroup]="assetForm" (ngSubmit)="onSubmit()">
    <table class="table table-striped table-hover mb-10">
        <thead>
            <tr>
                <th>Number</th>
                <th>Sev</th>
                <th>Phone</th>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let incident of data">
                <td>
                    <label class="form-radio">
                        <input type="radio" name="id_number" [value]="asset.id_number" formControlName="id_number" <i class="form-icon"></i>{{incident.number}}
                    </label></td>
                <td>{{incident.sev}}</td>
                <td>{{incident.phone}}</td>
            </tr>
        </tbody>
    </table>
    <button class="btn btn-primary" [disabled]="!Form.valid" type="submit">Select</button>
</form>
  

ts-файл:

     ngOnInit() {
    this.assetForm = new FormGroup({
        id_number: new FormControl(''),
    });
}

onSubmit() {
    if (this.assetForm.invalid) {
        this.assetForm.setErrors({
            ...this.assetForm.errors,
            'required': true
        });
        return;
    }
    this.uploading = true;
    this.service.postlist(this.assetForm.value).subscribe((response: any) => {
        console.log(response); //On success response
    }, (errorResponse: any) => {
        console.log(errorResponse); //On unsuccessful response
        this.error = true;
        this.uploading = false;
    });
}
  

Комментарии:

1. Посмотрите на строку расположения вашего браузера. Видите этот номер «55180593»? Это идентификатор вашего вопроса. При нажатии на вопрос в списке вопросов домашней страницы StackOverflow вы переходите на страницу, в URL-адресе которой указан идентификатор этого вопроса. То же самое следует сделать с Angular. И таким образом, если вы обновите страницу или добавите ее в закладки, вы немедленно вернетесь к этому вопросу. angular.io/guide/router

2. ДА… но каков был бы наилучший способ сделать это…

3. Чтение документации, на которую я ссылался, — это первый шаг. Вторая попытка — это попытка что-то сделать.

Ответ №1:

Лучше создать сервис, затем установить в нем значение и в нужном представлении / компоненте получить значение от сервиса. Если вы используете подход сервиса, и в какой-то момент, если страница по какой-либо причине обновилась, вы можете просто проверить идентификатор, существует ли он в сервисе или нет, и при необходимости легко перенаправить на нужный просмотр. Я бы не рекомендовал использовать локальное хранилище для одного и того же.

Например, создайте сервис, скажем S. У вас есть компоненты A, B и C. В компоненте A задайте необходимый идентификатор в службах, и к этому значению id можно будет получить доступ в B amp; C, внедрив службы в B amp; C.

app.module.ts

 import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { NgModule } from '@angular/core';
import { AppRoutesModule } from './app.routes';
import { AppComponent } from './app.component';
import { AComponent } from './acomponent.ts';
import { BComponent } from './bcomponent.ts';
import { CComponent } from './ccomponent.ts';
import { CustomService } from './custom.service';

@NgModule({
  declarations: [
    AppComponent,
    AComponent,
    BComponent,
    CComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    AppRoutesModule,
  ],
  providers: [
   CustomService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
  

custom.service.ts

 import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable({
  providedIn: 'root'
})
export class CustomService {

   user_id: any;
   fetchDataURL = "http://localhost:3000/api/some-link";

   // Set data
   setUserId(id) {
       this.user_id = id;
   }

   // Fetch data
   getUserId() {
       return this.user_id;
   }

   // Fetch data which contains "user_id"
   fetchData(): Observable<any> {
       return this._http.get<any>(this.fetchDataURL, httpOptions)
       .pipe(
          retry(1),
          catchError(this.handleError)
       );
   }

   // Error handler - you can customize this accordingly 
   handleError(error) {
     let errorMessage = '';
     if (error.error instanceof ErrorEvent) {
       // client-side error
       errorMessage = `Error: ${error.error.message}`;
     } else {
       // server-side error
       errorMessage = `Error Code: ${error.status}nMessage: ${error.message}`;
     }
     return throwError(errorMessage);
   }
}
  

a.component.ts

 import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { CustomService } from './custom-service-location';

@Component({
  selector: 'component-a',
  templateUrl: './a.component.html'
})

export class AComponent  implements OnInit {

    fetchedData: any;
    constructor(private customService: CustomService) {}

    ngOninit() {
        this.getData();
    }


    // Fetch data
    getData() {
        this.customService.getData()
          .subscribe((data) => {
            console.log(data);
            this.fechedData = data;
            this.customService.setUserId(data.user_id); // Passing the user id to service
          },
          (error) => {
              // logic to handle error accordingly
          });
    }
}
  

b.component.ts

 import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { CustomService } from './custom-service-location';

@Component({
  selector: 'component-b',
  templateUrl: './b.component.html'
})

export class BComponent  implements OnInit {

    user_id: any;
    constructor(private customService: CustomService, private router: Router) {}

    ngOninit() {
        this.getData();
    }


    // Fetch user id from service
    getUserData(id) {
        this.customService.getUserId()
          .subscribe((data) => {
            this.user_id = data.user_id;
            if(this.user_id == null) {
                this.router.navigate(['/component-a-route']) // If the id is lost on some page refresh, redirect back to the needed page
            }
          },
          (error) => {
              // logic to handle error accordingly
          });
    }


    someOtherFunction() {
      // some other function with some other logic
    }
}
  

Как вы можете видеть выше, существует основной модуль «приложение», два компонента a amp; b и служебный файл. В компоненте A вы вызываете функцию fetchData, которая возвращает в ней «user_id» (предположим), вы устанавливаете идентификатор пользователя в пользовательской службе с помощью метода «setUserID()», затем вы можете получить его в компоненте b с помощью метода «getUserId()».

Я надеюсь, что вышесказанное проясняет ситуацию и это помогает.

Комментарии:

1. @Sole, я обновил ответ примерами кодов.