2015-12-01 22 views
6

Tôi đang gặp sự cố với mã sau.Typescript - TypeError myclass.myFunction không phải là chức năng

Điều cơ bản nên làm. Nó sẽ tải và phân tích cú pháp một tệp JSON đã cho. Và trong RequestListender, nó sẽ hiển thị ID và chuỗi Hello được trả về theo phương pháp ToString() trong Product.ts. Trường hợp tProduct.Id được hiển thị chính xác, phương pháp tProduct.ToString() không thành công với lỗi được nêu bên dưới.

Cảm ơn rất nhiều trước.

Thông báo lỗi:

TypeError: tProduct.ToString is not a function. 
(In 'tProduct.ToString()', 'tProduct.ToString' is undefined) 

File: Test.ts

var currentProduct = null as pvis.Product; 

function runTest(path) { 
    var request = new XMLHttpRequest(); 
    request.onload = loadRequestListener; 
    request.open("get", path, true); 
    request.send(); 
} 

function loadRequestListener() { 
    var tProduct : pvis.Product = JSON.parse(this.responseText); 
    if (tProduct.Id) { 
     currentProduct = tProduct; 
     alert('loaded with Id: ' + tProduct.Id); 
     alert('loaded with Content: ' + tProduct.ToString()); 
    } 
    else { 
     alert('product failed to load'); 
    } 

} 

Product.ts file

module pvis { 
    export class Product { 

     Id: string; 

     ToString():string { 
      return 'Hello'; 
     } 
    } 
} 

Phần HTML:

<body onload="runTest('assets/products/json/A379N.json')"> 

Các biên soạn Javascript:

var pvis; 
(function (pvis) { 
    var Product = (function() { 
     function Product() { 
     } 
     Product.prototype.ToString = function() { 
      return 'Hello'; 
     }; 
     return Product; 
    })(); 
    pvis.Product = Product; 
})(pvis || (pvis = {})); 
var currentProduct = null; 
function runTest(path) { 
    var request = new XMLHttpRequest(); 
    request.onload = loadRequestListener; 
    request.open("get", path, true); 
    request.send(); 
} 
function loadRequestListener() { 
    var tProduct = JSON.parse(this.responseText); 
    if (tProduct.Id) { 
     currentProduct = tProduct; 
     alert('loaded with Id: ' + tProduct.Id); 
     alert('loaded with Content: ' + tProduct.ToString()); 
    } 
    else { 
     alert('product failed to load'); 
    } 
} 

Các tsconfig.json (Tôi không chắc chắn nếu nó là có liên quan):

{ 
    "compilerOptions": { 
     "target": "ES5", 
     "removeComments": true, 
     "preserveConstEnums": true, 
     "out": "js/main.js", 
     "sourceMap": true 
    }, 
    "files": [ 
     "src/Test.ts" 
    ] 
} 

Trả lời

8

Dòng:

var tProduct : pvis.Product = JSON.parse(this.responseText); 

là sai. Lý do nó biên dịch chỉ là do JSON.parse trả lại any.

để sử dụng lớp Product bạn phải tạo một phiên bản bằng cách nào đó. Phân tích cú pháp JSON sẽ không làm điều này, nó sẽ đơn giản trả về một đối tượng có JSON được phân tích cú pháp trong nó, nó sẽ không là một thể hiện của lớp pvis.Product.

Nếu những gì bạn muốn làm là nhập kết quả JSON, bạn có thể làm điều đó với giao diện.Ví dụ nếu bạn có một đối tượng JSON trên biểu mẫu:

{ 
    id: "some value", 
    name: "some name", 
    count: 4 
} 

Bạn có thể gõ mà với giao diện:

interface myInterface { 
    id: string; 
    name: string; 
    count: number; 
} 

Và sử dụng nó như vậy:

var myParsedAndTypedJson: myInterface = JSON.parse("...."); 

Một đối tượng đã tạo như vậy sẽ không bao giờ có các phương thức tuy nhiên, nếu bạn muốn chức năng đó, bạn phải chuyển thông tin này vào một lớp có thể sử dụng nó như thế nào, ví dụ;

class myClass implements myInterface { 

    get id(): string { return this.initData.id; } 
    get name(): string { return this.initData.name; } 
    get count(): number { return this.initData.count; } 

    constructor(private initData: myInterface) { 

    } 

    public ToString() { 
     return this.id + ' ' + this.name + ' ' + this.count; 
    } 
} 

Ví dụ làm việc này có thể được tìm thấy here.

Bạn có thể muốn tra cứu cách làm việc với giao diện kiểu chữ và JSON để tìm hiểu thêm về cách hoạt động của tính năng này.

+0

Cách tiếp cận giao diện là bước đầu tiên của tôi. Hầu như bạn đã đăng nó. Tôi vừa lấy nó ra khỏi mẫu để giữ nó ngắn hơn. – FrW

+0

xin lỗi ... Tôi khá mới ở đây (nhấn nút Enter) vì vậy đây là câu trả lời hoàn chỉnh: Cách tiếp cận giao diện là bước đầu tiên của tôi. Hầu như bạn đã đăng nó. Tôi vừa xóa nó khỏi mẫu để giữ nó ngắn hơn vì giao diện không phải là một phần của vấn đề. Như bạn và @ Dustin-Hodges đã nói, vấn đề là với JSON.parse và điều đó không tạo ra một cá thể. Mà tôi đã giả định. ** Cảm ơn bạn đã hỗ trợ ** và cho tôi hướng đi đúng. – FrW

+0

Không vấn đề gì, tôi đã cập nhật câu trả lời của mình để sửa một số lỗi trong mã của mình và cung cấp ví dụ đang chạy. Vui mừng được giúp đỡ! – Nypan

1

Tôi không quen thuộc với TypeScript, nhưng nhìn vào JavaScript đã biên dịch, tôi nhận thấy rằng tProduct i chỉ là một POJO, không phải là một thể hiện của lớp Sản phẩm (tức là tProduct instanceof Product === false).

Lý do Id không có lỗi là do JSON.parse trả về một đối tượng có thuộc tính Id.

Để xem làm thế nào để deserialize một loại nguyên cảo, bạn có thể kiểm tra các câu trả lời sau đây: How do I initialize a typescript object with a JSON object

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