2014-11-05 1 views
1

Google DataVisualization을 사용자 정의하고 싶지만 컨트롤의 생성자를 매개 변수화하려고했지만 어떤 이유로 인해 inputDataTable을 매개 변수로 전달할 때 작동하지 않는 것처럼 보입니다.Websharper/Web.Control 생성자 문제

module Example = 
    let headers = [|"Country"; "Population (mil)"; "Area (km2)" |] 
    let inputDataTable = [| 
    [|box "CN"; box 1234000; box 9640821|] 
    [|box "IN"; box 1133000; box 3287263|] 
    [|box "US"; box 304000; box 9629091|] 
    [|box "ID"; box 232000; box 1904569|] 
    [|box "BR"; box 187000; box 8514877|] 
    |] 

코드는 웹 페이지에 차트를 생성 : 여기

내가 사용하는 기본 데이터입니다.

let GeoChart headers inputDataTable = 
    Div [] 
    |>! OnAfterRender (fun container -> 
      let dataFormatter = DefaultOptions.NumberFormatter "" 
      let options = DefaultOptions.GeoChart 
      let visualization = new GeoChart(container.Dom) 
      let data = Data.GeoMapData headers inputDataTable 
      dataFormatter.format(data, 1) 
      visualization.draw(data, options) 
     ) 

"예상 됨"컨트롤입니다.

type GoogleGeoChartViewer(headers, inputDataTable) = 
    inherit Web.Control() 

    [<JavaScript>] 
    override this.Body = 
    Google.Charts.GeoChart headers inputDataTable :> _ 

기본 템플릿을 사용한 테스트.

let HomePage = 
    let headers = Google.Example.headers 
    let inputDataTable = Google.Example.inputDataTable 
    Skin.WithTemplate "HomePage" <| fun ctx -> 
     [ 
      Div [Text "HOME"] 
      Div [new Controls.EntryPoint()] 
      Div [new Controls.GoogleGeoChartViewer(headers, inputDataTable)] 
      Links ctx 
     ] 

그러나이 코드를 사용할 때 : 지오 차트가 표시되지 않습니다.

하지만 매개 변수 목록에서 inputDataTable를 제거하고 사용하는 경우 :

let GeoChart headers = 
    Div [] 
    |>! OnAfterRender (fun container -> 
      let dataFormatter = DefaultOptions.NumberFormatter "" 
      let options = DefaultOptions.GeoChart 
      let visualization = new GeoChart(container.Dom) 
      let inputDataTable = Example.inputDataTable 
      let data = Data.GeoMapData headers inputDataTable 
      dataFormatter.format(data, 1) 
      visualization.draw(data, options) 
     ) 

의미가 있습니다 ...

headers 배열 그러나 어떤 문제를 제기하지 않습니다.

아무도 어떤 일이 벌어지고 있는지 알 수 있습니까?

통찰력을 가져 주셔서 감사합니다.

답변

1

Web.Control의 생성자에 전달 된 값은 페이지의 서버 측 구성 중에 JSON에 직렬화되는 서버 측 값입니다. 그러나 형식이 obj 인 serializer가 없으므로 inputDataTable (형식 : obj[][])의 serialization이 실패합니다. 반대로 작동하는 버전에서는 inputDataTable이 클라이언트에서 생성되므로 직렬화를 수행 할 필요가 없습니다.

실제로 서버 측에서 inputDataTable이 필요하면 직렬화 가능 유형을 사용해야합니다. 난 당신이 GeoMapData 기능에 데이터 개체를 채우는 방법을 정확하게 모르겠지만,이 솔루션은 다음과 같이 inputDataTable을 정의하는 아마 :

: 뭔가를 클라이언트 측에 다음

let inputDataTable = [| 
    ("CN", 1234000, 9640821) 
    ("IN", 1133000, 3287263) 
    ("US", 304000, 9629091) 
    ("ID", 232000, 1904569) 
    ("BR", 187000, 8514877) 
    |] 

및 수행

let data = new Base.DataTable() 
data.addRows(inputDataTable) |> ignore 

WebSharper는 클라이언트 측에서 JavaScript 배열을 사용하는 튜플을 나타냅니다. 그리고 obj[][]을 취하는 addRows 방법은 또한 'T[]을 필요로하는 오버로드를 가지고 있습니다. 위 형식의 F # 코드를 올바르게 작성할 수 있으며 obj[][]을 전달하는 것과 똑같은 JavaScript 코드로 컴파일됩니다. 이 트릭은 this example (줄 155)에서 사용됩니다.

+0

설명해 주셔서 감사합니다. 필자는 제네릭 함수를 갖고 싶었 기 때문에지도에 원하는만큼의 시리즈를 추가 할 수있었습니다 (특히 지오 차트가 아닌, 강도 차트와 같은 다른 것들). 그래서 제가 obj [ ] []보다 직관적 인 (string * double ...) []. obj를 사용하여 주위를 둘러 보지 않도록하십시오. – user1251614