elmish - 等同于 Elm 风格的 model-view-update 中的数据绑定模型更新
问题描述
MVU 状态变化
据我了解 Elm 风格的模型-视图-更新架构,应用程序状态的更改遵循定义更新状态的消息的发送。这里的状态是不可变的,因此更改会导致一组全新的应用程序状态。
例如,在下面(取自Fabulous项目)中,Pressed
消息导致状态Model.Pressed
变为true
。
我相信该消息将由于用户采取明确的操作而发送,例如单击提交或保存。
/// The messages dispatched by the view
type Msg =
| Pressed
/// The model from which the view is generated
type Model =
{ Pressed: bool }
/// Returns the initial state
let init() = { Pressed = false }
/// The function to update the view
let update (msg: Msg) (model: Model) =
match msg with
| Pressed -> { model with Pressed = true }
/// The view function giving updated content for the page
let view (model: Model) dispatch =
if model.Pressed then
View.Label(text="I was pressed!")
else
View.Button(text="Press Me!", command=(fun () -> dispatch Pressed))
type App () as app =
inherit Application ()
let runner =
Program.mkSimple init update view
|> Program.withConsoleTrace
|> Program.runWithDynamicView app
数据绑定状态更改
假设您在 WPF 中有一个模型,它可能实现INotifyPropertyChanged
并使用数据绑定将您的状态附加到用户界面。所以,这里的状态是可变的,并且会随着时间而改变。
当用户输入新值时,模型会因数据绑定而更新,而无需显式保存或提交。因此,模型中的任何计算值都将随着用户输入值而更新。Age
这是一个在输入新出生日期时更新值的模型示例。
public class PersonView: INotifyPropertyChanged
{
private DateTime _birthday;
public DateTime Birthday
{
get { return _birthday; }
set
{
_birthday = value;
PropertyChanged("Birthday");
Age = CalculateAgeFromBirthday();
}
}
private int _age;
public int Age
{
get { return _age; }
private set
{
_age = value;
PropertyChanged("Age");
}
}
void PropertyChanged(string property)
{
// Etc.
}
int CalculateAgeFromBirthday()
{
// Do you sums here;
}
}
问题
我的问题是,在 Elm 风格的模型-视图-更新架构中是否有等效的方法来创建一个用户界面,当用户以与可变模型的数据绑定视图类似的方式输入值时更新这些“计算的属性”?
解决方案
假设您在 WPF 中有一个模型...
如果您想将 Elmish 与 WPF 一起使用,那么我建议您使用Elmish.WPF。该 repo 包含许多非常适合快速理解的示例。
我的问题是,在 Elm 风格的模型-视图-更新架构中是否有等效的方法来创建一个用户界面,当用户以与可变模型的数据绑定视图类似的方式输入值时更新这些“计算的属性”?
我看到有两种方法可以做到这一点。
- 在您的
update
函数中,除了更新到新输入的数据外,还显式计算派生数据。 - 在您的绑定中,计算派生数据。
推荐阅读
- visual-studio-code - 如何使用 Rust VS Code 扩展解决“无法启动客户端 Rust 语言服务器”?
- google-apps-script - 使用 Google 脚本创建 Twitter 投票
- wordpress - 如何在 Woocommerce 中使用“非常简单的验证码”?
- css - 我可以在 Rmarkdown 中使用 {.tabset} 和 CSS 样式表创建垂直标签吗?
- android - Google Fit API - 如何从历史客户端读取 DataType.TYPE_STEP_COUNT_CADENCE
- c# - 我想打印频率最高的数字
- python - 将 Docker 运行转换为 Kubernetes 的问题
- python - 不同窗口大小的熊猫分组滚动平均值 - 不同时期的移动平均值
- identityserver4 - 如何找出在 IdentityServer 中使用最佳流程?
- c# - Blazor 中的缓存标识帮助程序