我正在创建一个编辑屏幕,我希望人们从列表中删除项目。列表正常显示,直到"控制器"对象进入编辑模式。然后用户可以删除项目。项目应标记为删除并显示,然后当用户保存编辑时,将删除它们并通知服务器。
我实际上已经完成了所有工作,但我能做到的唯一方法就是在绑定中使用字面条件,这看起来很丑陋而且我并不喜欢。有没有更好的方法呢?
工作小提琴:http://jsfiddle.net/L1e7zwyv/
标记:
<div id="test">
<a data-bind="visible: IsViewMode, click: edit">Edit</a>
<a data-bind="visible: IsEditMode, click: cancel">Cancel</a>
<hr/>
<ul data-bind="foreach: Items">
<li data-bind="css: CssClass">
<span data-bind="visible: $parent.IsViewMode() || $data._Deleting(), text: Value"></span>
<!-- ko if: $parent.IsEditMode() && !$data._Deleting() -->
<input type="text" data-bind="value: Value"/>
<a data-bind="click: $parent.deleteItem">Del</a>
<!-- /ko -->
</li>
</ul>
</div>
代码:
function ItemModel(val)
{
var _this = this;
this.Value = ko.observable(val);
this._Deleting = ko.observable();
this.CssClass = ko.computed(
function()
{
return _this._Deleting() ? 'deleting' : '';
}
);
}
function ManagerModel()
{
var _this = this;
this.Items = ko.observableArray([
new ItemModel('Hell'),
new ItemModel('Broke'),
new ItemModel('Luce')
]);
this.IsEditMode = ko.observable();
this.IsViewMode = ko.computed(function() { return !_this.IsEditMode(); });
this.edit = function(model, e)
{
this.IsEditMode(true);
};
this.cancel = function(model, e)
{
for(var i = 0; i < _this.Items().length; i++)
_this.Items()[i]._Deleting(false);
this.IsEditMode(false);
};
this.deleteItem = function(model, e)
{
model._Deleting(true);
};
}
ko.applyBindings(new ManagerModel(), document.getElementById('test'));
答案 0 :(得分:0)
visible:
和if:
绑定来实现相同的功能,isVisible()
上编写一个函数,接受父作为参数进行绑定visible: $data.isVisible($parent)
。// reprisent variables from models
var v1 = false;
var v2 = false;
var v3 = false;
// Helper functions defined in main script body - globally accessible
function VisibilityFromAny() {
var result = false;
for(var i = 0; i < arguments.length; i++ ) result |= arguments[i];
return Boolean(result);
}
function VisibilityFromAll() {
var result = true;
for(var i = 0; i < arguments.length; i++ ) result &= arguments[i];
return Boolean(result);
}
// represent bindings
alert(VisibilityFromAny(v1, v2, v3));
alert(VisibilityFromAll(v1, v2, v3));
第三个选项是最受欢迎的技术,MVVM爱好者就像你自己一样,在我看到的单个绑定中组合变量,它是有意义的,并且保持所有逻辑远离视图模型中的视图标记。
就个人而言,我喜欢你目前的语法,(尽管我自己也算是MVVM爱好者团伙之一),这在视图标记中清楚地表明该元素的可见性被绑定到2个项目,而不是隐藏这些细节在一个函数中。
答案 1 :(得分:0)
我尝试将视图模型视为我视图的模型,而不仅仅是逻辑所在的位置。如果可能的话,我还尝试将复杂的逻辑移回视图模型,并为我的变量使用描述性名称,以便代码更具可读性。
我建议将其添加到您的视图模型中 -
var isViewable = ko.computed(function () { return IsViewMode() || _Deleting(); });
var isEditable = ko.computed(function() { return IsEditMode() && !_Deleting(); });
在您看来 -
<li data-bind="css: CssClass">
<span data-bind="visible: isViewable, text: Value"></span>
<!-- ko if: isEditable -->
<input type="text" data-bind="value: Value"/>
<a data-bind="click: $parent.deleteItem">Del</a>
<!-- /ko -->
</li>
这样可以清除绑定并允许您更轻松地调整逻辑,而无需在视图和视图模型中进行许多健全性检查。另外,我个人将返回一个布尔值的变量命名为,因为它有助于更具描述性。
好处是随着您的视图和视图模型变大,您可以保持DOM清洁混乱,并且您的视图模型也变得可测试。
这是一个完整的代码&#39;你添加 -
的小提琴版本