Tìm kiếm trang web

Cách thiết lập các tham số lớp tùy chọn trong Angular 2-Typescript?


Tôi biết trong Typescript các tham số tùy chọn có thể được đánh dấu bằng dấu hỏi.

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

Vấn đề là dựa trên lớp hướng dẫn bắt đầu "hero" của Angular 2, các lớp không được khởi tạo thông qua từ khóa new và theo như tôi hiểu, điều đó được Angular thực hiện nội bộ.

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

models/users.ts

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

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

dịch vụ/user.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));
   }
}

Câu trả lời #1

Trong trường hợp của bạn, có thể sẽ tiện hơn nếu sử dụng một giao diện cho User.

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

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

Nếu bạn thực sự cần một lớp, thì cú pháp để tạo các thể hiện của Users trong mock-users.ts sẽ hơi khác. Trước hết, không có "các trường tùy chọn" trong TypeScript. Bất kỳ trường nào cũng có thể không được thiết lập/'undefined', vì vậy việc đánh dấu một trường là tùy chọn là không hợp lý. 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 viết một hàm khởi tạo để đặt giá trị các trường hoặc gán thể hiện đó cho một biến rồi đặt các trường. Nhưng không có gì sai khi sử dụng từ khóa new, đặc biệt là cho các đối tượng thử nghiệm.

Bạn cũng có thể khởi tạo một đối tượng bằng một literal đối tượng như bạn đã làm trong mock-users.ts - bạn cần phải rõ ràng hơn bằng cách thêm một ép kiểu.

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ó ép kiểu, trình biên dịch TypeScript sẽ báo lỗi. Đây là thiết kế nhằm phát hiện lỗi. 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 liên quan về một số suy nghĩ đằng sau việc kiểm tra kiểu:

  • Tại sao tôi lại nhận được lỗi "Object literal chỉ có thể chỉ định các thuộc tính đã biết"?

  • https://basarat.gitbooks.io/typescript/content/docs/types/freshness.html

Bài viết liên quan