【发布时间】:2014-08-20 04:11:45
【问题描述】:
通常我可以想办法让 Knockout-js 做我想做的事。然而,在这种情况下,我有点挣扎,所以我在 SO 上向社区提出这个问题。
简介
我正在使用 typescript、bootstrap、knockoutjs 和 nodejs 后端编写一个 HTML5 网络应用程序。
在我的 UI 中,所有这些都通过 knockoutJS 进行控制,我有一组按钮,形成一个引导 3 按钮组的可选选项。
这个合理的组,给我 4 个水平按钮,但允许按钮选择的行为与一组选项按钮保持一致。
一致性很重要,因为一次只能选择一个按钮,所以当一个按钮被点击时,其余的取消选择。
这是 BS3 中的默认组件,如下图所示:
正如您在图像中看到的那样,选择了“丢弃”按钮,为了实现这一点,必须将“活动”类添加到构成控件的内部单选元素周围的标签元素的现有类列表中.以下 HTML 用于创建此图像:
<div class="btn-group btn-group-justified" data-toggle="buttons">
<label class="btn btn-primary">
<input type="radio" name="options" id="option1" checked >Rejected
</label>
<label class="btn btn-primary active">
<input type="radio" name="options" id="option2">Discarded
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option3">Held
</label>
<label class="btn btn-primary">
<input type="radio" name="options" id="option3">Header Added
</label>
</div>
这一切都很好,除了一个小缺陷,我正在使用淘汰赛 JS 来管理 UI。
我要解决的问题
每个选项的选中状态都与应用于 HTML 的视图模型内的属性相关联,因此例如被拒绝按钮上的内部选项添加了一个普通的 knockout-js 选中绑定,如下所示:
<input type="radio" name="options" id="option1" checked data-bind="checked: reject">Rejected
每个选项,每个选项都有自己的支持字段:
reject
discard
hold
addheader
这些支持字段中的每一个都是一个标准的布尔值,持有真/假,我不知道如何在封闭标签上添加/删除“活动”类,以反映这些状态中的哪一个已选中。
更准确地说,我想不出最好的优雅方式。
我尝试过的方法
我所知道的工作是为每个返回的标签添加一个简单的计算 observable
"btn btn-primary active"
当该选项设置为 true 时,并且
"btn btn-primary"
如果不是。
我知道这一点,因为在我的视图模型中,我有一个简单的函数:
SenderDialogViewModel.prototype.isRejectSelected = function () {
if (this.reject == true) {
return "btn btn-primary active";
}
return "btn btn-primary";
};
但是,这种方法意味着 4 个函数,每个标记一个要测试,因此很难在以后添加新标记。
我想做的事情如下:
<label class="btn btn-primary" data-bind="class: isSelected(reject)">
举个例子。
我几乎要对上述内容稍作修改:
SenderDialogViewModel.prototype.isSelected = function (selectionVariable) {
if (selectionVariable == true) {
return "active";
}
return "";
};
其中选择变量可以是视图模型中可用的任何标志,传入。
这里的问题是,这仅在第一次绘制 UI 时更新,随后对标志的更改未能更新 UI 以反映给定状态。
为了尝试解决这个问题,我将函数更改为计算的 observable,然后在绘制 UI 时收到 JS 错误,说明计算的 observable 必须添加一个“写入”处理程序,因为我正在传入一个参数。
如果我需要添加一个写处理程序,那很好,但我不想这样做。
总结
总而言之,有一些方法可以与其他选项同步更改类列表,但其中大多数都很混乱,我想做的是创建一种在添加新按钮时易于扩展的方法(这是重要,因为一些按钮集是动态生成的),而不是添加一个处理程序来单独检查和报告那里的每个变量的状态,在一个函数调用中可以简单地添加到视图模型中并一次又一次地重复使用.
【问题讨论】:
-
我会创建一个自定义绑定,因为这会将 ViewModel 与 DOM 分离
-
是的,我已经想到了,不过上次我做了一个自定义绑定,它变得非常混乱,非常快。但是,我似乎刚刚得出了答案,因此已将其正式发布到问题上。
标签: javascript html twitter-bootstrap user-interface knockout.js