2013-05-28 30 views
12

Tôi đang sử dụng TypeScript để tạo một số lớp với KnockoutJS, với dữ liệu đang được tải từ một số JSON được trả về bởi WebAPI.Khởi tạo các giá trị của lớp Typecript từ hàm tạo

Vấn đề là tôi muốn sao chép các giá trị JSON vào lớp TypeScript của tôi từ hàm dựng: nhưng nếu tôi làm điều này ngay tại lớp cơ sở, các thuộc tính kế thừa chưa được xác định và do đó không được khởi tạo.

Ví dụ

Chúng tôi muốn tạo một mục hàng tồn kho từ một phản ứng JSON:

{ Name: "Test", Quantity:1, Price: 100 } 

Tôi có một lớp cơ sở sản phẩm và một lớp Inventory thừa hưởng:

export class Product { 
    Name = ko.observable(""); 

    constructor(source) { 
    // a utility that copies properties into this instance 
    utils.CopyProperties(source,this); 
    } 

export class Inventory extends Product { 
    Quantity = ko.observable(0); 
    Price = ko.observable(0); 

    constructor(source) { 
    super(source); // call base c'tor 
    // the quantity and price properties are only now defined 
    } 
} 

Các thuộc tính cho Khoảng không quảng cáo chỉ được tạo trong mã đầu ra JS sau cuộc gọi hàm tạo siêu, do đó không tồn tại khi cấu trúc Sản phẩm hoặc được thực hiện.

Giải pháp duy nhất tôi có thể thấy là lấy giá trị khởi tạo ra khỏi hàm tạo, nhưng tôi không thực sự thích phương pháp này, mặc dù tôi nghi ngờ đó là tùy chọn duy nhất.

var inventoryItem = new Inventory(); 
    inventoryItem.LoadFrom(source); 
+0

Mục đích sao chép thuộc tính vào thể hiện cơ sở là gì? Có xấu không nếu Số lượng và Giá được xác định sau bản sao? – BSick7

+0

Tôi không chắc mình hiểu vấn đề là gì. Hàm khởi tạo của 'Product' sẽ đặt' Name' từ 'source' và hàm tạo' Inventory' sẽ đặt 'Quantity' và' Price' từ 'source' – MiMo

+0

Vấn đề là bạn phải gọi thuộc tính copy hai lần: không có ý nghĩa. Nếu bạn vừa làm điều đó trong lớp Product, nó sẽ chỉ thiết lập Name. Nếu bạn chỉ làm điều đó trong Inventory, bạn không gọi nó trong Product, vì vậy bất cứ thứ gì tạo ra một sản phẩm sẽ không được khởi tạo – Quango

Trả lời

8

tốt nhất tôi có thể đưa ra để cho phép bạn có một thói quen cơ sở deserialization đó được gọi là từ các nhà xây dựng được này (sửa đổi để loại bỏ loại trực tiếp phụ thuộc để thử nghiệm):

class utils { 
    public static CopyProperties(source:any, target:any):void { 
     for(var prop in source){ 
      if(target[prop] !== undefined){ 
       target[prop] = source[prop]; 
      } 
      else { 
       console.error("Cannot set undefined property: " + prop); 
      } 
     } 
    } 
} 

class Product { 
    Name = "Name"; 

    constructor(source) { 
    this.init(source); 
    } 

    init(source){ 
    utils.CopyProperties(source,this); 
    } 
} 

class Inventory extends Product { 
    Quantity; 
    Price; 

    constructor(source) { 
    super(source); 
    } 

    init(source){ 
     this.Quantity = 0; 
     this.Price = 0; 
     super.init(source); 
    } 
} 

var item = new Inventory({ Name: "Test", Quantity: 1, Price: 100 }); 

lẻ mà các biến được chỉ khởi tạo trong JS sau khi cuộc gọi đến super(). Có thể có giá trị raising a work item on codeplex?

Playground.

+0

Cảm ơn bạn đã gợi ý: có một bộ khởi tạo như thế là một lựa chọn tốt. Tôi không nghĩ rằng đó là một lỗi trong TypeScript, như tôi mong đợi nó hoạt động theo cách của nó. Đó là bản chất động của JS: không có siêu dữ liệu và phản chiếu nào hoạt động, không giống như C# etc – Quango

+0

Đồng ý. Một sự kỳ quặc, chứ không phải là một lỗi. – JcFx

3

Cách tiếp cận này dường như làm việc cho tôi:

/// <reference path="knockout.d.ts" /> 

export class Product { 
    Name: KnockoutObservableString; 

    constructor(source) { 
     this.Name = ko.observable(source.Name); 
    } 
} 

export class Inventory extends Product { 
    Quantity: KnockoutObservableNumber; 
    Price: KnockoutObservableNumber; 

    constructor(source) { 
     super(source); 
     this.Quantity = ko.observable(source.Quantity); 
     this.Price = ko.observable(source.Price); 
    } 
} 

var item = new Inventory({ Name: "Test", Quantity: 1, Price: 100 }); 
+0

Cảm ơn .. điều đó cũng sẽ hoạt động nhưng một khi bạn bắt đầu thêm nhiều biến nó làm cho mã hóa tẻ nhạt. Tôi sẽ thử ý tưởng JcFX đầu tiên – Quango

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