感谢您对此进行调查。
我制作了以下示例:http://jsfiddle.net/zm381qjx/5/
这是一个菜单列表构建器。添加菜单时,会弹出一个编辑表单。使用protectedObservable以便我可以提交或重置(根据代码)。我遇到问题的一个功能是,有单选按钮列表(对于TypeId),并且根据值(10 = Url,20 = Category,30 = Page),您可以设置相应的属性(10 = Url, 20 = CategoryId,30 = PageId)。
点击单选按钮,如果选择了Url,则应显示另一个文本框(基于urlVisible),以便用户可以输入Url。我添加了一个带文本的span:TypeId.temp所以我可以看到临时值。这非常不规律。尝试多次轻弹。
非常感谢任何帮助。
我的HTML
<a class="btn btn-primary" data-bind="click: addMenu">Add Menu</a>
<ul data-bind="foreach: Menus">
<li><a href="#" data-bind="text: Name, click: editMenu"></a></li>
</ul>
<div class="panel panel-default" data-bind="slideIn: editMenuItem, with: editMenuItem">
<div class="panel-body">
<div class="form-group">
<label for="MenuName">Name: </label>
<input type="text" id="MenuName" data-bind="value: Name" class="form-control" />
</div>
<label class="radio-inline">
<input type="radio" name="MenuTypeId" value="10" data-bind="checked: TypeId" /> Url
</label>
<label class="radio-inline">
<input type="radio" name="MenuTypeId" value="20" data-bind="checked: TypeId" /> Category
</label>
<label class="radio-inline">
<input type="radio" name="MenuTypeId" value="30" data-bind="checked: TypeId" /> Page
</label>
<div class="form-group" data-bind="visible: urlVisible">
<label for="MenuUrl">Url: </label>
<input type="text" id="MenuUrl" data-bind="value: Url" class="form-control" />
</div>
<br />
<p>TypeId.temp = <span data-bind="text: TypeId.temp"></span></p>
<br /><br />
<input type="button" class="btn btn-success" value="Update" data-bind="click: commit" /> or
<a href="#" data-bind="click: reset">Cancel</a>
</div>
</div>
我的JS:
var vm = null;
//wrapper for an observable that protects value until committed
ko.protectedObservable = function (initialValue) {
//private variables
var _temp = ko.observable(initialValue);
var _actual = ko.observable(initialValue);
var result = ko.dependentObservable({
read: function () {
return _actual();
},
write: function (newValue) {
_temp(newValue);
}
});
//commit the temporary value to our observable, if it is different
result.commit = function () {
var temp = _temp();
if (temp !== _actual()) {
_actual(temp);
}
};
//notify subscribers to update their value with the original
result.reset = function () {
_actual.valueHasMutated();
_temp(_actual());
};
result.temp = _temp;
return result;
};
ko.bindingHandlers.slideIn = {
init: function (element) {
$(element).hide();
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
if (value) {
$(element).stop().hide().slideDown('fast');
} else {
$(element).stop().slideUp('fast');
}
}
};
var Menu = function (Id, Name, TypeId, CategoryId, PageId, Url) {
var self = this;
/* Core Properties */
self.Id = ko.observable(Id);
self.Name = ko.protectedObservable(Name);
self.TypeId = ko.protectedObservable(TypeId);
self.CategoryId = ko.protectedObservable(CategoryId);
self.PageId = ko.protectedObservable(PageId);
self.Url = ko.protectedObservable(Url);
/* Virtual Properties */
self.urlVisible = ko.computed(function () {
return self.TypeId.temp() == "10";
}, self);
/* Virtual Functions */
self.editMenu = function (data) {
if(vm.editMenuItem()) {
vm.editMenuItem(null);
}
vm.editMenuItem(data);
};
/* Core Functions */
self.commit = function () {
if (self.Name.temp() == '' || self.Name.temp() == null) {
alert('Please enter a name.'); return;
}
self.Name.commit();
self.TypeId.commit();
self.CategoryId.commit();
self.PageId.commit();
self.Url.commit();
vm.editMenuItem(null);
};
self.reset = function () {
self.Name.reset();
self.TypeId.reset();
self.CategoryId.reset();
self.PageId.reset();
self.Url.reset();
vm.editMenuItem(null);
};
};
var ViewModel = function() {
var self = this;
/* Core Properties */
self.Menus = ko.observableArray([]);
/* Virtual Properties */
self.editMenuItem = ko.observable(null);
self.addMenu = function(){
var menu = new Menu(0, "New Menu", "10", 0, 0, "");
self.Menus.push(menu);
self.editMenuItem(menu);
};
};
$(function () {
vm = new ViewModel();
ko.applyBindings(vm);
});
答案 0 :(得分:1)
如果您将单选按钮绑定更改为
<input type="radio" name="MenuTypeId" value="10" data-bind="checked: TypeId.temp" />
临时ID将相应更改,单选按钮行为是一致的,但不是TypeId作为值。
还是protectedObservable绑定单选按钮值不好玩
当您手动点击收音机时,TypeId值永远不会改变(因为您没有提交该值),我想由于单选按钮值永远不会从10更改,因此无法识别后续手动点击Url单选按钮
我使用按钮更新了值,并且相应地改变了;但是它不会在随后的单选按钮点击中移动该TypeId的值
问题仍然出现在protectedObservable绑定中,但不是一个简单的observable。
进一步探讨这个想法的代码:http://jsfiddle.net/zm381qjx/101/