способ отправки для родительской дочерней композиции - PullRequest
0 голосов
/ 07 декабря 2018

Я пытаюсь понять, как басня должна работать с родительской дочерней композицией.Все довольно просто, когда дело доходит до метода update, init и определения команд.Но метод view и его метод dispatch сложно найти

В моем коде дочерний элемент:

module DeploymentView

type DeploymentTypeView =
    | DeployContainerView

type Model = { 
 CurrentView : DeploymentTypeView option
}

type Msg =
| ShowDeployContainer

let init () : Model =
    let initialModel = { 
        CurrentView = None
    }
    initialModel


let update (msg : Msg) (currentModel : Model) : Model * Cmd<Msg> = 
    match msg with 
    | ShowDeployContainer ->
        let nextModel = { 
            currentModel with CurrentView = Some DeployContainerView 
        }
        nextModel, Cmd.none     
    | _ -> currentModel, Cmd.none


let view (model : Model) (dispatch : Msg -> unit) =
    [
        Content.content [ Content.Modifiers [ Modifier.TextAlignment (Screen.All, TextAlignment.Left) ] ]
            [ 
                Heading.h3 [] [ str ("Deployments: ") ] 
            ] 

        Columns.columns []
            [ 
                Column.column [] [ button "deploy container" (fun _ -> dispatch ShowDeployContainer) ]
            ] 
    ]

И, следуя этой документации Что касается обработки родительских и дочерних объектов, я определил родителя как этот:

module Client

type PortalView =
| DeploymentView of DeploymentView.Model
| ProductAdministrationView


type Model = { 
    CurrentPortal : PortalView option
}

// The Msg type defines what events/actions can occur while the application is running
// the state of the application changes *only* in reaction to these events
type Msg =
| ShowDeployment
| ShowAdministration
| DeployContainerView of DeploymentView.Msg


// defines the initial state and initial command (= side-effect) of the application
let init () : Model * Cmd<Msg> =
    let initialModel = { 
        CurrentPortal = None 
    }
    initialModel, Cmd.none

let update (msg : Msg) (currentModel : Model) : Model * Cmd<Msg> =
    match  msg with
    | ShowDeployment ->
        let nextModel = { 
            currentModel with CurrentPortal = Some <| DeploymentView(DeploymentView.init())
        }
        nextModel, Cmd.none
    | ShowAdministration ->
        let nextModel = { 
            currentModel with CurrentPortal = Some ProductAdministrationView
        }
        nextModel, Cmd.none
    | DeployContainerView msg' ->
        let res, cmd = 
            match currentModel.CurrentPortal with
            | Some(DeploymentView(m)) -> DeploymentView.update msg' m
            | _ -> DeploymentView.init(), Cmd.none
        { currentModel with CurrentPortal = Some(DeploymentView(res)) }, Cmd.map DeployContainerView cmd

Пока все хорошо, моя проблема возникает, когда речь идет о рендеринге самого представления.Клиентское представление использует функцию следующим образом:

let view (model : Model) (dispatch : Msg -> unit) 

, где Msg имеет тип DeploymentView.Msg, тогда как в родительском представлении у меня есть доступ к отправке типа Client.Msg -> unit.как я могу разложить родительскую диспетчеризацию, чтобы сопоставить ее с дочерней сигнатурой диспетчеризации?

1 Ответ

0 голосов
/ 08 декабря 2018

Вы можете очень легко создать функцию отправки, которая соответствует ожиданиям ребенка, используя оператор >>:

DeploymentView.view deploymentViewModel (DeployContainerView >> dispatch)

, что эквивалентно выполнению:

DeploymentView.view deploymentViewModel (fun msg -> msg |> DeployContainerView |> dispatch)

То есть он оборачивает сообщение дочернего элемента в DeployContainerView, а затем передает его в dispatch.

С другой стороны, общепринято и хорошо использовать суффикс Msg для конструкторов, используемых для переноса.ребенок msg типов.Вы можете рассмотреть вопрос о переименовании DeployContainerView в DeploymentContainerMsg.

...