Definire le costanti globali


258

In Angular 1.x puoi definire costanti come questa:

angular.module('mainApp.config', [])
    .constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/')

Quale sarebbe l'equivalente in angolare (con TypeScript)?

Non voglio ripetere più volte l'URL della base API in tutti i miei servizi.

Risposte:


265

Di seguito le modifiche funzionano per me sulla versione finale di Angular 2:

export class AppSettings {
   public static API_ENDPOINT='http://127.0.0.1:6666/api/';
}

E poi nel servizio:

import {Http} from 'angular2/http';
import {Message} from '../models/message';
import {Injectable} from 'angular2/core';
import {Observable} from 'rxjs/Observable';
import {AppSettings} from '../appSettings';
import 'rxjs/add/operator/map';

@Injectable()
export class MessageService {

    constructor(private http: Http) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(AppSettings.API_ENDPOINT+'/messages')
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    }

    private parseData(data): Message {
        return new Message(data);
    }
}

Penso che la tua AppSettingsclasse dovrebbe essere astratta e il API_ENDPOINTmembro dovrebbe esserlo readonly.
Philippe Gioseffi,

164

La soluzione per la configurazione fornita dalla stessa squadra angolare è disponibile qui .

Ecco tutto il codice rilevante:

1) app.config.ts

import { OpaqueToken } from "@angular/core";

export let APP_CONFIG = new OpaqueToken("app.config");

export interface IAppConfig {
    apiEndpoint: string;
}

export const AppConfig: IAppConfig = {    
    apiEndpoint: "http://localhost:15422/api/"    
};

2) app.module.ts

import { APP_CONFIG, AppConfig } from './app.config';

@NgModule({
    providers: [
        { provide: APP_CONFIG, useValue: AppConfig }
    ]
})

3) your.service.ts

import { APP_CONFIG, IAppConfig } from './app.config';

@Injectable()
export class YourService {

    constructor(@Inject(APP_CONFIG) private config: IAppConfig) {
             // You can use config.apiEndpoint now
    }   
}

Ora puoi inserire la configurazione ovunque senza usare i nomi delle stringhe e con l'uso della tua interfaccia per i controlli statici.

Naturalmente è possibile separare l'interfaccia e la costante oltre a poter fornire valori diversi nella produzione e nello sviluppo, ad es


3
Funziona solo quando non specifico il tipo nel costruttore del servizio. Quindi funziona quando faccio il costruttore (@Inject (APP_CONFIG) config privata) {} Ne parliamo qui: blog.thoughtram.io/angular/2016/05/23/…, ma non perché.
Mukus,

Suppongo che ti sia sfuggita qualche parola chiave di importazione o esportazione o qualcosa del genere, dal momento che la utilizzo con l'interfaccia ed è come dici molto importante averla esplicitamente digitata staticamente. Forse devi fornire un'eccezione esatta qui.
Ilya Chernomordik,

46
Nessuna di queste soluzioni, anche l'approccio raccomandato dal team angolare sembra elegante. Perché cercare di creare costanti è un processo complicato in Angular 2? Non vedi quanto Angular1 è stato realizzato senza soluzione di continuità? Perché tutto il casino?
KhoPhi,

31
Per chiunque ottenga questa risposta, OpaqueToken in Angular v4 è "deprecato" per InjectionToken - blog.thoughtram.io/angular/2016/05/23/…
mtpultz

3
Avrebbe senso mettere il codice dal punto 1 in environment.tse environment.prod.tsin modo che si può avere diverse costanti per ambiente? @IlyaChernomordik ha iniziato a menzionarlo nell'ultimo paragrafo della sua risposta.
Robert Bernstein,

64

In Angular2, hai la seguente definizione fornire , che ti consente di impostare diversi tipi di dipendenze:

provide(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}

Confronto con angolare 1

app.servicein Angular1 è equivalente a useClassin Angular2.

app.factoryin Angular1 è equivalente a useFactoryin Angular2.

app.constanted app.valueè stato semplificato useValuecon meno vincoli. cioè non c'è configpiù nessun blocco.

app.provider - Non esiste un equivalente in Angular 2.

Esempi

Per impostare con l'iniettore di root:

bootstrap(AppComponent,[provide(API_ENDPOINT, { useValue='http://127.0.0.1:6666/api/' })]);

O imposta con l'iniettore del componente:

providers: [provide(API_ENDPOINT, { useValue: 'http://127.0.0.1:6666/api/'})]

provide è una scorciatoia per:

var injectorValue = Injector.resolveAndCreate([
  new Provider(API_ENDPOINT, { useValue: 'http://127.0.0.1:6666/api/'})
]);

Con l'iniettore, ottenere il valore è semplice:

var endpoint = injectorValue.get(API_ENDPOINT);

2
In realtà vorrei avere le mie impostazioni in un file esterno, ad esempio: settings.ts Come sarebbe questo file?
AndreFeijo,

Hai considerato javascript sul lato server come NodeJS?
pixelbits

5
Scusa, non ho capito come lo inserirò nel mio servizio? Dato che sto usando un file esterno, devo esportarlo?
AndreFeijo,

Vorrei renderlo parte del processo di configurazione della build. cioè in base al proprio ambiente, compilare / impacchettare insieme diversi file, quindi distribuirli. Tutto ciò che puoi fare con NodeJS con i moduli appropriati.
pixelbits

1
Sfortunatamente NodeJS non è un'opzione.
AndreFeijo,

59

In Angular 4, puoi utilizzare la classe di ambiente per mantenere tutti i tuoi globali.

Hai environment.ts e environment.prod.ts per impostazione predefinita.

Per esempio

export const environment = {
  production: false,
  apiUrl: 'http://localhost:8000/api/'
};

E poi al tuo servizio:

import { environment } from '../../environments/environment';
...
environment.apiUrl;

Se si sta tentando di accedere a constun'all'interno di un servizio, potrebbe essere necessario "fornire" in serie fornitori del modulo app: { provide: 'ConstName', useValue: ConstName }. Stavo ottenendo un errore di runtime senza questo.
Daleyjem,

@daleyjem è perché stavi cercando di iniettarlo. Questo approccio non utilizza l'iniettore
Aluan Haddad,

Creare una costante come questa è la più semplice. Immagino che l'argomento contrario di perdere DI e quindi perdere testability / mockValue sia un po 'troppo pubblicizzato. Nell'app tipica usiamo così tanti componenti non DI come (RxJS) senza disturbare la testabilità.
Amitesh,

54

Aggiornato per Angular 4+

Ora possiamo semplicemente usare il file degli ambienti che angolare fornisce di default se il tuo progetto viene generato tramite angular-cli.

per esempio

Nella cartella degli ambienti, creare i seguenti file

  • environment.prod.ts
  • environment.qa.ts
  • environment.dev.ts

e ogni file può contenere modifiche al codice correlate come:

  • environment.prod.ts

    export const environment = {
         production: true,
         apiHost: 'https://api.somedomain.com/prod/v1/',
         CONSUMER_KEY: 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
  • environment.qa.ts

    export const environment = {
         production: false,
         apiHost: 'https://api.somedomain.com/qa/v1/',
         CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };
  • environment.dev.ts

    export const environment = {
         production: false,
         apiHost: 'https://api.somedomain.com/dev/v1/',
         CONSUMER_KEY : 'someReallyStupidTextWhichWeHumansCantRead', 
         codes: [ 'AB', 'AC', 'XYZ' ],
    };

Caso d'uso nell'applicazione

È possibile importare ambienti in qualsiasi file come i servizi clientUtilServices.ts

import {environment} from '../../environments/environment';

getHostURL(): string {
    return environment.apiHost;
  }

Caso d'uso in build

Apri il tuo file cli angolare .angular-cli.jsone all'interno "apps": [{...}]aggiungi il seguente codice

 "apps":[{
        "environments": {
            "dev": "environments/environment.ts",
            "prod": "environments/environment.prod.ts",
            "qa": "environments/environment.qa.ts",
           }
         }
       ]

Se vuoi compilare per la produzione, eseguilo ng build --env=prodleggerà la configurazione environment.prod.ts, nello stesso modo in cui puoi farlo per qaodev

## Risposta precedente

Ho fatto qualcosa di simile al seguito, nel mio provider:

import {Injectable} from '@angular/core';

@Injectable()
export class ConstantService {

API_ENDPOINT :String;
CONSUMER_KEY : String;

constructor() {
    this.API_ENDPOINT = 'https://api.somedomain.com/v1/';
    this.CONSUMER_KEY = 'someReallyStupidTextWhichWeHumansCantRead'
  }
}

Quindi ho accesso a tutti i dati Constant ovunque

import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';

import {ConstantService} from  './constant-service'; //This is my Constant Service


@Injectable()
export class ImagesService {
    constructor(public http: Http, public ConstantService: ConstantService) {
    console.log('Hello ImagesService Provider');

    }

callSomeService() {

    console.log("API_ENDPOINT: ",this.ConstantService.API_ENDPOINT);
    console.log("CONSUMER_KEY: ",this.ConstantService.CONSUMER_KEY);
    var url = this.ConstantService.API_ENDPOINT;
    return this.http.get(url)
  }
 }

6
Questo non funziona come una costante. Il valore di una costante è sempre lo stesso. Nel tuo caso, il tuo API_ENDPOINTvalore può essere sovrascritto in qualsiasi momento. Se this.ConstantService.API_ENDPOINT = 'blah blah'viene dichiarato nella classe in qualsiasi momento dopo l'importazione della cosiddetta "costante" da constant-service, il nuovo valore di API_ENDPOINT sarà 'blah blah'. La tua soluzione mostra semplicemente come accedere a una variabile usando un servizio e non usando una costante.
Devner,

1
@Devner li rendi di sola letturareadonly API_ENDPOINT :String;
Flavien Volken il

@Anjum Come angolare seleziona i file env. Devo passare il nome env all'avvio dell'app?
notionquest

@notionquest Sì, puoi passarlo, tipong build --env=prod
Anjum ....

31

Mentre l'approccio con avere una classe AppSettings con una costante di stringa mentre funziona ApiEndpoint, non è l'ideale poiché non saremmo in grado di scambiare questo ApiEndpoint reale con altri valori al momento del test unitario.

Dobbiamo essere in grado di iniettare questi endpoint API nei nostri servizi (pensate di iniettare un servizio in un altro servizio). Inoltre, non è necessario creare un'intera classe per questo, tutto ciò che vogliamo fare è iniettare una stringa nei nostri servizi come ApiEndpoint. Per completare l' eccellente risposta di pixelbit , ecco il codice completo su come può essere fatto in Angular 2:

Per prima cosa dobbiamo dire ad Angular come fornire un'istanza del nostro ApiEndpoint quando la richiediamo nella nostra app (pensala come registrazione di una dipendenza):

bootstrap(AppComponent, [
        HTTP_PROVIDERS,
        provide('ApiEndpoint', {useValue: 'http://127.0.0.1:6666/api/'})
]);         


E poi nel servizio che iniettare questo ApiEndpoint al costruttore servizio e angolare forniremo per noi sulla base della nostra registrazione di cui sopra:

import {Http} from 'angular2/http';
import {Message} from '../models/message';
import {Injectable, Inject} from 'angular2/core';  // * We import Inject here
import {Observable} from 'rxjs/Observable';
import {AppSettings} from '../appSettings';
import 'rxjs/add/operator/map';

@Injectable()
export class MessageService {

    constructor(private http: Http, 
                @Inject('ApiEndpoint') private apiEndpoint: string) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(`${this.apiEndpoint}/messages`)
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    } 
    // the rest of the code...
}

1
Ora c'è un modo "ufficiale" di fare raccomandazioni da parte del team angolare nel loro tutorial. Ho aggiunto una risposta qui sotto: ( stackoverflow.com/a/40287063/1671558 )
Ilya Chernomordik

1
questo codice non è più preciso, l'implementazione causerà un ApiEndpoint non trovato su AppComponent.
WilliamX,

Ok, quindi non sono solo. Sai quale versione ha rotto? Esiste un modo alternativo che non richiede la definizione di valori su un oggetto globale e la loro fornitura?
Jens Bodal,

29

Questa è la mia recente esperienza con questo scenario:

  • @ angolare / cli: 1.0.0
  • nodo: 6.10.2
  • @ angolare / core: 4.0.0

Ho seguito i documenti ufficiali e aggiornati qui:

https://angular.io/docs/ts/latest/guide/dependency-injection.html#!#dependency-injection-tokens

Sembra OpaqueToken ora è deprecato e dobbiamo usare InjectionToken , quindi questi sono i miei file in esecuzione come un incantesimo:

app-config.interface.ts

export interface IAppConfig {

  STORE_KEY: string;

}

app-config.constants.ts

import { InjectionToken } from "@angular/core";
import { IAppConfig } from "./app-config.interface";

export const APP_DI_CONFIG: IAppConfig = {

  STORE_KEY: 'l@_list@'

};

export let APP_CONFIG = new InjectionToken< IAppConfig >( 'app.config' );

app.module.ts

import { APP_CONFIG, APP_DI_CONFIG } from "./app-config/app-config.constants";

@NgModule( {
  declarations: [ ... ],
  imports: [ ... ],
  providers: [
    ...,
    {
      provide: APP_CONFIG,
      useValue: APP_DI_CONFIG
    }
  ],
  bootstrap: [ ... ]
} )
export class AppModule {}

my-service.service.ts

  constructor( ...,
               @Inject( APP_CONFIG ) private config: IAppConfig) {

    console.log("This is the App's Key: ", this.config.STORE_KEY);
    //> This is the App's Key:  l@_list@

  }

Il risultato è pulito e non ci sono avvisi sulla console grazie al recente commento di John Papa in questo numero:

https://github.com/angular/angular-cli/issues/2034

La chiave era implementare in un altro file l'interfaccia.


vedi anche stackoverflow.com/a/43193574/3092596 - che è sostanzialmente lo stesso, ma crea moduli iniettabili piuttosto che provider
goredwards,

19

Tutte le soluzioni sembrano essere complicate. Sto cercando la soluzione più semplice per questo caso e voglio solo usare le costanti. Le costanti sono semplici. C'è qualcosa che parla contro la seguente soluzione?

app.const.ts

'use strict';

export const dist = '../path/to/dist/';

app.service.ts

import * as AppConst from '../app.const'; 

@Injectable()
export class AppService {

    constructor (
    ) {
        console.log('dist path', AppConst.dist );
    }

}

2
Bene, stai usando le variabili al di fuori dell'ambito del servizio in modo da poter usare solo i globali delle finestre. Quello che stiamo cercando di fare è inserire costanti nel sistema di iniezione di dipendenza Angular4 in modo da poter mantenere l'oscilloscopio pulito, stabile e beffardo.
Joel Hernandez,

11

Usa solo una costante dattiloscritta

export var API_ENDPOINT = 'http://127.0.0.1:6666/api/';

Puoi usarlo nell'iniettore di dipendenza usando

bootstrap(AppComponent, [provide(API_ENDPOINT, {useValue: 'http://127.0.0.1:6666/api/'}), ...]);

1
Perché iniettarlo? Non ce n'è bisogno, penso ... puoi usarlo non appena lo importi. @SnareChops
Sasxa

@Sasxa Sono d'accordo, anche se potrebbe essere buono per i test unitari e simili. Sto solo cercando di fornire una risposta completa.
SnareChops

1
@Andreas Si potrebbe utilizzare constyest
SnareChops

Fornisci uno stackblitz di questo funzionamento. Ho visto tanti esempi di fornire un servizio nel metodo bootstrap ma devo ancora trovarne uno con un esempio sufficientemente funzionante. Forse qualcosa è cambiato in una versione più recente di angolare.
Jens Bodal,

4

Se stai usando Webpack , che consiglio, puoi impostare costanti per ambienti diversi. Ciò è particolarmente utile quando si hanno valori costanti diversi in base all'ambiente.

Probabilmente avrai più file webpack nella tua /configdirectory (es. Webpack.dev.js, webpack.prod.js, ecc.). Quindi avrai un custom-typings.d.tsli aggiungerai lì. Ecco il modello generale da seguire in ogni file e un esempio di utilizzo in un componente.

Webpack. {env} js

const API_URL = process.env.API_URL = 'http://localhost:3000/';
const JWT_TOKEN_NAME = "id_token";
...
    plugins: [
      // NOTE: when adding more properties, make sure you include them in custom-typings.d.ts
      new DefinePlugin({
        'API_URL': JSON.stringify(API_URL),
        'JWT_TOKEN_NAME': JSON.stringify(JWT_TOKEN_NAME)
      }),

custom-typings.d.ts

declare var API_URL: string;
declare var JWT_TOKEN_NAME: string;
interface GlobalEnvironment {
  API_URL: string;
  JWT_TOKEN_NAME: string;
}

Componente

export class HomeComponent implements OnInit {
  api_url:string = API_URL;
  authToken: string = "Bearer " + localStorage.getItem(JWT_TOKEN_NAME)});
}

3

L'uso di un file delle proprietà che viene generato durante una compilazione è semplice e facile. Questo è l'approccio utilizzato dalla CLI angolare. Definisci un file delle proprietà per ciascun ambiente e usa un comando durante la compilazione per determinare quale file viene copiato nella tua app. Quindi importare semplicemente il file delle proprietà da utilizzare.

https://github.com/angular/angular-cli#build-targets-and-environment-files


3

Un approccio per Angular4 sarebbe la definizione di una costante a livello di modulo:

const api_endpoint = 'http://127.0.0.1:6666/api/';

@NgModule({
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: [
    MessageService,
    {provide: 'API_ENDPOINT', useValue: api_endpoint}
  ]
})
export class AppModule {
}

Quindi, al tuo servizio:

import {Injectable, Inject} from '@angular/core';

@Injectable()
export class MessageService {

    constructor(private http: Http, 
      @Inject('API_ENDPOINT') private api_endpoint: string) { }

    getMessages(): Observable<Message[]> {
        return this.http.get(this.api_endpoint+'/messages')
            .map(response => response.json())
            .map((messages: Object[]) => {
                return messages.map(message => this.parseData(message));
            });
    }

    private parseData(data): Message {
        return new Message(data);
    }
}

3

Ho un altro modo per definire le costanti globali. Perché se abbiamo definito nel file ts, se compilato in modalità di produzione non è facile trovare costanti per cambiare valore.

export class SettingService  {

  constructor(private http: HttpClient) {

  }

  public getJSON(file): Observable<any> {
      return this.http.get("./assets/configs/" + file + ".json");
  }
  public getSetting(){
      // use setting here
  }
}

Nella cartella dell'app, aggiungo le cartelle configs / setting.json

Contenuto in setting.json

{
    "baseUrl": "http://localhost:52555"
}

Nel modulo dell'app aggiungi APP_INITIALIZER

   {
      provide: APP_INITIALIZER,
      useFactory: (setting: SettingService) => function() {return setting.getSetting()},
      deps: [SettingService],
      multi: true
    }

in questo modo, posso cambiare più facilmente il valore nel file json. Uso questo modo anche per messaggi di errore / avviso costanti.


0

AngularJS module.constantnon definisce una costante in senso standard.

Mentre si distingue da solo come meccanismo di registrazione del provider, è meglio compreso nel contesto della funzione related module.value( $provide.value). La documentazione ufficiale indica chiaramente il caso d'uso:

Registra un servizio valore con $ injector, come una stringa, un numero, un array, un oggetto o una funzione. Questo è abbreviato per la registrazione di un servizio in cui la proprietà $ get del suo provider è una funzione factory che non accetta argomenti e restituisce il servizio valore. Ciò significa anche che non è possibile iniettare altri servizi in un servizio di valore.

Confrontalo con la documentazione di module.constant( $provide.constant) che indica chiaramente anche il caso d'uso (enfasi sulla mia):

Registra un servizio costante con $ injector, come una stringa, un numero, un array, un oggetto o una funzione. Come il valore, non è possibile iniettare altri servizi in una costante. Ma a differenza del valore, una costante può essere iniettata in una funzione di configurazione del modulo (vedi angular.Module) e non può essere ignorata da un decoratore AngularJS .

Pertanto, la constantfunzione AngularJS non fornisce una costante nel significato comunemente compreso del termine nel campo.

Detto questo, le restrizioni poste sull'oggetto fornito, insieme alla sua precedente disponibilità tramite l'iniettore $, suggeriscono chiaramente che il nome è usato per analogia.

Se volessi una costante effettiva in un'applicazione AngularJS, "forniresti" uno come faresti in qualsiasi programma JavaScript che è

export const π = 3.14159265;

In Angular 2 è applicabile la stessa tecnica.

Le applicazioni Angular 2 non hanno una fase di configurazione nello stesso senso delle applicazioni AngularJS. Inoltre, non esiste alcun meccanismo di decoratore di servizi ( AngularJS Decorator ), ma ciò non sorprende particolarmente, dato quanto differiscono l'uno dall'altro.

L'esempio di

angular
  .module('mainApp.config', [])
  .constant('API_ENDPOINT', 'http://127.0.0.1:6666/api/');

è vagamente arbitrario e leggermente scoraggiante perché $provide.constantviene utilizzato per specificare un oggetto che per inciso è anche una costante. Potresti anche aver scritto

export const apiEndpoint = 'http://127.0.0.1:6666/api/';

perché tutti e due possono cambiare.

Ora l'argomento per la testabilità, deridendo la costante, è diminuito perché letteralmente non cambia.

Non si deride π.

Ovviamente la semantica specifica dell'applicazione potrebbe essere che il tuo endpoint potrebbe cambiare, o l'API potrebbe avere un meccanismo di failover non trasparente, quindi sarebbe ragionevole che l'endpoint API cambi in determinate circostanze.

Ma in quel caso, fornirlo come una rappresentazione letterale stringa di un singolo URL per la constantfunzione non avrebbe funzionato.

Un argomento migliore, e probabilmente un altro in linea con il motivo dell'esistenza della $provide.constantfunzione AngularJS , è che, quando fu introdotto AngularJS, JavaScript non aveva un concetto di modulo standard . In tal caso, i globali verrebbero usati per condividere valori, mutabili o immutabili, e l'uso dei globali è problematico.

Detto questo, fornire qualcosa di simile attraverso un framework aumenta l'accoppiamento con quel framework. Mescola anche la logica angolare specifica con la logica che funzionerebbe in qualsiasi altro sistema.

Questo non vuol dire che è un approccio sbagliato o dannoso, ma personalmente, se voglio una costante in un'applicazione Angular 2, scriverò

export const π = 3.14159265;

proprio come avrei usato AngularJS.

Più cose cambiano ...


0

Il modo migliore per creare costanti a livello di applicazione in Angular 2 è utilizzare i file environment.ts. Il vantaggio di dichiarare tali costanti è che è possibile modificarle in base all'ambiente in quanto esiste un file di ambiente diverso per ciascun ambiente.


Questo non funziona se si intende compilare l'applicazione una volta, quindi distribuirla in più ambienti.
Jens Bodal,

-1

Puoi creare una classe per la tua variabile globale e quindi esportare questa classe in questo modo:

export class CONSTANT {
    public static message2 = [
        { "NAME_REQUIRED": "Name is required" }
    ]

    public static message = {
        "NAME_REQUIRED": "Name is required",
    }
}

Dopo aver creato ed esportato la tua CONSTANTclasse, dovresti importare questa classe in quella classe in cui vuoi usare, in questo modo:

import { Component, OnInit                       } from '@angular/core';
import { CONSTANT                                } from '../../constants/dash-constant';


@Component({
  selector   : 'team-component',
  templateUrl: `../app/modules/dashboard/dashComponents/teamComponents/team.component.html`,
})

export class TeamComponent implements OnInit {
  constructor() {
    console.log(CONSTANT.message2[0].NAME_REQUIRED);
    console.log(CONSTANT.message.NAME_REQUIRED);
  }

  ngOnInit() {
    console.log("oninit");
    console.log(CONSTANT.message2[0].NAME_REQUIRED);
    console.log(CONSTANT.message.NAME_REQUIRED);
  }
}

Puoi usarlo in constructoro ngOnInit(){}, o in qualsiasi metodo predefinito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.