2016-04-20 14 views
17

so a macchina opzionali parametri possono essere contrassegnati da Mark domanda.Come impostare i parametri di classe opzionali in angolare 2-tipografico?

Tuttavia, l'unico modo in cui ho trovato effettivamente istanziare la classe con nuova parola chiave.

Il fatto è che sulla base di avviamento angolare 2 di "eroe" classi di tutorial sono non istanziati tramite la nuova parola chiave e per quanto ho capito questo è fatto internamente da angolare.

Per esempio io ho questo codice:

modelli/users.ts

export class User { 
    id: number; 
    name: string; // I want this to be optional 
} 

modelli/mock-users.ts

import {User} from './user'; 

export var USERS: User[] = [ 
    { 
     id: 1 
     // no name (I wanted it to be optional for user with id 1) 
    }, 
    { 
     id: 2, 
     name: "User 2" 
    },   
] 

servizi/utente. service.ts

import {Injectable} from 'angular2/core'; 
import {USERS} from './../models/mock-users'; 

@Injectable() 
export class UserService { 
    getUsers() { 
     return Promise.resolve(USERS); 
    } 
} 

viste/my-component.component.ts

// imports here... 

@Component({ 
    // ... 
}) 

export class MyComponent { 
    constructor(private _userService: UserService) { } 

    getUsers() { 
     this._userService.getUsers().then(users => console.log(users)); 
    } 
} 

risposta

28

Nel tuo caso, potrebbe essere più conveniente utilizzare un'interfaccia per l'utente, invece.

export interface User { 
    id: number; 
    name?: string; // interfaces allow fields to be optional 
} 

Io uso le interfacce quando voglio definire la 'forma' di un oggetto, le classi quando ho bisogno di aggiungere un comportamento (metodi). Se tutto ciò di cui hai bisogno è spostare i dati, utilizzerei un'interfaccia.

Se è necessaria una classe, la sintassi per la creazione di istanze di utenti in mock-users.ts dovrebbe essere leggermente diversa. Innanzitutto, non ci sono "campi di classe opzionali" in TypeScript. Qualsiasi campo non può essere impostato/'undefined', in modo che non ha senso contrassegnare un campo facoltativo. È possibile creare un'istanza di una classe con la parola chiave new - il lato negativo è che è necessario scrivere un costruttore per impostare i valori di campo o assegnare l'istanza a un campi variabili e impostare. Ma non c'è niente di sbagliato con l'utilizzo della nuova parola chiave, in particolare per gli oggetti di prova.

Puoi anche istanziare un oggetto con un oggetto letterale come hai fatto in mock-users.ts - devi essere più esplicito aggiungendo un cast.

export var USERS: User[] = [ 
    <User> { // explicit cast to let the TypeScript compiler know you know what you're doing 
     id: 1 
     // no name (I wanted it to be optional for user with id 1) 
    }, 
    { 
     id: 2, 
     name: "User 2" 
    },   
] 

Senza il cast, il compilatore TypeScript genera un errore. Questo è progettato per cogliere errori.Se vuoi sapere di più sulle ragioni (interessanti), ecco una relativa discussione dettagliate su alcuni la filosofia che ispira il controllo dei tipi:

+0

grazie Ronald.could si fornisce un esempio completo si prega (utilizzo)? – dragonmnl

+0

Se tutto il codice che hai è nella domanda, cambiare la parola chiave da 'class' a' interface' dovrebbe fare il trucco. Espanderò la risposta. –

+0

grazie per l'ulteriore spiegazione. Lo farò. Potresti spiegare cosa devo fare quando voglio sia parametri che metodi facoltativi? inoltre, nel caso di una classe con metodi, devo creare un'istanza con una nuova chiave di volta? dopo questo accetterò la tua risposta :) – dragonmnl

1
class User { 
    constructor(public id: number, public name: string = null) {} 
} 

var USERS: User[] = [ 
    new User(1), 
    new User(2, 'User 2') 
]; 

console.log(USERS); 

JsFiddle

L'utilizzo di un costruttore probabilmente renderà la tua vita molto più semplice. Non si ottiene undefined quando si tenta di ottenere il nome di un utente e sarà possibile definire funzioni sulla classe. L'unica differenza è che useresti new User(...) invece di usare solo un oggetto letterale come tipo.

0

Un altro modo è quello di utilizzare Object.assign per estendere un oggetto tipizzato valida con la proprietà è necessario solo (omettendo proprietà a e c in questo esempio)

export class A { 
    a:number=1; 
    b:number; 
    c:string; 
    d:string; 
} 

let validA:A = Object.assign(new A(),{ 
    b:3, 
    d:'Lorem ipsum' 
}); 

ho personnaly preferisco questa sintassi per evitare l'inizializzazione oggetto multilinea e la cosa noiosa per creare un'interfaccia (quindi un altro file abbastanza inutile se esiste una classe corrispondente) per ogni modello della mia app.

Inoltre, non esitare a impostare il valore predefinito nella definizione della classe, anche se non è obbligatorio per questo caso.

Un'ultima cosa importante è che tu non metodi di classe sciolti in questo caso (contrapposte a {} casting)