2016-01-13 12 views
12

How to implement a typescript decorator? là một ví dụ tốt về cách sử dụng trang trí trong bản in.Làm thế nào để vượt qua một biến dụ vào các đối số trang trí kiểu chữ?

Xét trường hợp dưới đây,

class MyClass { 
    @enumerable(false) 
    get prop() { 
     return true; 
    } 

    @property({required: true}) //here pass constant is no issue 
    public startDateString:string; 

    @property({afterDate: this.startDateString}) //how to pass startDateString here? 
    public endDateString:string; 
} 

function enumerable(isEnumerable: boolean) { 
    return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => { 
     descriptor.enumerable = isEnumerable; 
     return descriptor; 
    }; 
} 

tôi đã cố gắng tất cả mọi thứ nhưng có vẻ như tôi không có cách nào để vượt qua startDateString vào lập luận trang trí. startDateString có thể là một biến, hàm và tham chiếu.

+0

Điều này có thể xảy ra tùy thuộc vào _how_ và _when_ bạn cần sử dụng giá trị được chuyển. Tôi nhận được nó rằng bạn cần phải vượt qua ... errrr ... _instance value_ của 'startDateString' đến trang trí được áp dụng cho' endDateString', nhưng bạn định làm gì với _do_ với nó trong trang trí? Tùy thuộc vào hoàn cảnh, nó có thể nhận được một thành viên cá thể thông qua một trang trí. –

Trả lời

6

Điều bạn đang cố gắng làm là không thể.

Trang trí được gọi khi lớp được khai báo và tại thời điểm này không có trường hợp nào để chuyển vào trình trang trí.

Ví dụ, với mã này:

class MyClass { 
    startDateString: string; 
    @property({ afterDate: this.startDateString }) 
    endDateString: string; 
} 
let myClass = new MyClass(); 
  1. MyClass được khai báo.
  2. Bộ trang trí được chạy trên MyClass. Không có cá thể nào tồn tại để chuyển vào lúc này và this trong đối số trang trí tham chiếu đến đối tượng chung - không phải là một cá thể.
  3. new MyClass() được gọi và phiên bản được tạo. Trang trí không được gọi trên bước này. Điều đó đã xảy ra.

Hãy xem JavaScript biên soạn để tham khảo:

var MyClass = (function() { 
    // -- 1 -- 
    function MyClass() { 
    } 
    // -- 2 -- 
    __decorate([ 
     // see here... `this` is equal to the global object 
     property({ afterDate: this.startDateString }) 
    ], MyClass.prototype, "endDateString", void 0); 
    return MyClass; 
})(); 
// -- 3 -- 
var myClass = new MyClass(); 

Lưu ý rằng việc sử dụng this.startDateString không ném một lỗi biên dịch ở đây vì this được gõ như any.

Vì vậy, những gì đang cố gắng được thực hiện ở đây bằng cách chuyển vào một thuộc tính cá thể không có ý nghĩa và không thể thực hiện được.

Những gì bạn có thể làm là tạo startDateString tĩnh rồi chuyển vào như sau: @property({ afterDate: MyClass.startDateString }).

+0

Cảm ơn. Nhưng trong trường hợp của tôi, nó không thể tĩnh để trở thành một biến lớp. Nó phải là một biến cá thể. – new2cpp

+0

@ new2cpp một điều bạn có thể làm là chuyển vào một chuỗi hoặc một hàm được truyền một thể hiện của lớp và trả về giá trị thuộc tính. Một cái gì đó như '{afterDate:" startDateString "}' hoặc '{afterDate: (instance: MyClass) => instance.startDate}'. Sau đó bạn có thể sử dụng thông tin này sau khi bạn có một thể hiện của lớp để lấy giá trị của thuộc tính. Đó là một giải pháp hacky là một cách tuyệt vời để gây nhầm lẫn cho mọi người khi xem mã. –

3

Bạn không thể truy cập vào thuộc tính đối tượng từ định nghĩa thuộc tính.

Trang trí được gọi khi thuộc tính được xác định.

Bạn có thể sử dụng getter hoặc setter để có quyền kiểm soát khi truy cập vào thuộc tính.

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