2016-04-20 34 views
17

Tôi biết trong các thông số tùy chọn có thể được đánh dấu bằng dấu chấm hỏi.Làm thế nào để thiết lập các tham số lớp tùy chọn trong Angular 2-Typescript?

Tuy nhiên, cách duy nhất tôi thấy thực sự khởi tạo lớp học với từ khóa mới.

Điều này dựa trên các lớp hướng dẫn "anh hùng" khởi động của Angular 2 là không phải là được khởi tạo qua từ khóa mới và theo như tôi hiểu được nội bộ được thực hiện bởi Angular.

Ví dụ tôi có mã này:

mô hình/users.ts

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

mô hình/mô hình 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" 
    },   
] 

dịch vụ/người dùng. service.ts

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

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

views/my-component.component.ts

// imports here... 

@Component({ 
    // ... 
}) 

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

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

Trả lời

28

Trong trường hợp của bạn, nó có thể là thuận tiện hơn để sử dụng một giao diện cho người thay thế.

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

Tôi sử dụng giao diện khi tôi muốn xác định 'hình dạng' của đối tượng, lớp khi tôi cần thêm hành vi (phương pháp). Nếu tất cả những gì bạn cần là di chuyển dữ liệu xung quanh, tôi sẽ sử dụng một giao diện.

Nếu bạn cần một lớp, thì cú pháp để tạo phiên bản Người dùng trong mock-users.ts sẽ khác đôi chút. Thứ nhất, không có "trường lớp tùy chọn" trong TypeScript. Bất kỳ trường nào có thể không được thiết lập/'không xác định', do đó, nó không có nghĩa là đánh dấu một trường tùy chọn. Bạn có thể khởi tạo một lớp với từ khóa new - nhược điểm là bạn cần phải viết một hàm tạo để thiết lập các giá trị trường hoặc gán cá thể cho một trường biến và thiết lập. Nhưng không có gì sai khi sử dụng từ khóa mới, đặc biệt là đối với các đối tượng thử nghiệm.

Bạn cũng có thể khởi tạo đối tượng bằng một đối tượng theo nghĩa đen như bạn đã thực hiện trong mock-users.ts - bạn cần rõ ràng hơn bằng cách thêm một diễn viên.

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" 
    },   
] 

Nếu không có diễn viên, trình biên dịch TypeScript sẽ tạo ra lỗi. Điều này là do thiết kế để bắt một sai lầm.Nếu bạn muốn biết thêm về những lý do (thú vị), đây là một cuộc thảo luận chi tiết có liên quan về một số suy nghĩ đằng sau việc kiểm tra loại:

+0

cảm ơn Ronald. Bạn có thể cung cấp một ví dụ đầy đủ xin vui lòng (sử dụng)? – dragonmnl

+0

Nếu tất cả các mã bạn có trong câu hỏi, sau đó thay đổi từ khóa từ 'lớp' sang' giao diện' nên thực hiện thủ thuật. Tôi sẽ mở rộng câu trả lời. –

+0

cảm ơn vì đã giải thích thêm. Tôi sẽ làm việc đó. Bạn có thể vui lòng giải thích những gì tôi nên làm gì khi tôi muốn cả hai thông số tùy chọn và phương pháp? Ngoài ra, trong trường hợp của một lớp học với các phương pháp, tôi có cần phải nhanh chóng với keywork mới không? sau này tôi sẽ chấp nhận câu trả lời của bạn :) – 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

Sử dụng một nhà xây dựng có thể sẽ làm cho cuộc sống của bạn dễ dàng hơn nhiều. Bạn sẽ không nhận được undefined khi bạn cố gắng lấy tên người dùng và bạn sẽ có thể xác định các chức năng trên lớp. Điểm khác biệt duy nhất là bạn sử dụng new User(...) thay vì chỉ sử dụng một đối tượng theo nghĩa đen như một loại.

0

Một cách khác là sử dụng Object.assign để mở rộng một đối tượng đánh máy có giá trị với thuộc tính bạn chỉ cần (bỏ qua bất động sản ac trong ví dụ này)

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

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

tôi personnaly thích cú pháp này để tránh nhiều dòng khởi động đối tượng và điều nhàm chán để tạo ra một giao diện (vì vậy một tệp khác khá vô dụng nếu một lớp coresponding tồn tại) cho mỗi mô hình ứng dụng của tôi.

Ngoài ra, đừng ngần ngại đặt giá trị mặc định trong định nghĩa lớp học của bạn, ngay cả khi nó không bắt buộc đối với trường hợp này.

Một điều quan trọng cuối cùng là bạn không mất phương pháp lớp học trong trường hợp này (đối lập với {} đúc)

Các vấn đề liên quan