Knockout:在改变可观察数组后设置select的标题
Knockout: Set caption of select after changing observable array
我有一个绑定到属性对象的ko.observableArray()
的选择:
<select title="Select Property"
data-bind="options: $root.properties,
optionsCaption: '- Select Property -',
optionsText: 'name',
optionsValue: 'typeId',
value: $root.columns()[index]
"></select>
当有选择时,select元素显示被选择的名称。这工作了一段时间,但现在我需要修改properties
observableArray后的选择。一旦我这样做,选择就会返回到optionsCaption。
本页底部是
部分注2:对生成的选项进行后处理
我认为这可以帮助我将选择设置回显示name
,但我还没有弄清楚如何。
除非我可以使用JQuery抓取选择和设置名称?
我想这样写:
$("select[title='Select Property']").setAttribute();
但是选择是在ko foreach中生成的,所以我必须指定元素的索引才能获得它(如何?),即使这样,我也不确定如何使JQuery与knockout一起发挥良好。
我有没有说过我还在学习这些东西?
谢谢。
------------------ EDIT ------------------
显示我如何修改数组:
我从subscribeChanged
得到newValue
和oldValue
,然后
if (typeof(newValue) != "undefined") {
var newProperty = model.allProperties[newValue];
if (model.properties.indexOf(newProperty) != -1) {
model.properties.splice(model.properties.indexOf(newProperty), 1);
}
model.propertiesInUse[newValue] = index;
}
if (typeof(oldValue) != "undefined") {
var oldProperty = model.allProperties[oldValue];
if (model.properties.indexOf(oldProperty) == -1) {
model.properties.unshift(oldProperty);
}
if (model.propertiesInUse[oldValue]) {
delete model.propertiesInUse[oldValue];
}
}
就我对你情况的理解
-你需要创建一个动态下拉列表,任何添加的下拉列表都会更新为尚未被选择的值。
-如果一个下拉菜单被删除并且有一个选定的值,该值需要重新添加到其他下拉菜单。
下面是我的方法:
示例:https://jsfiddle.net/9aLvd3uw/251/
HTML:<!-- ko foreach: MainPropertiesList -->
<select title="Select Property" data-bind="value:SelectedValue">
<option data-bind="value:'',text:'-Select Property -'"></option>
<!-- ko foreach: Options -->
<option data-bind="value:typeId,text:name"></option>
<!-- /ko -->
</select>
<span data-bind="text:'remove',click:$root.deleteColumn"></span>
<!-- /ko -->
<hr>
<span data-bind="text:'add',click:$root.addColumn"></span>
JS:
var data = [{name:"Property1",typeId:1},{name:"Property2",typeId:2},{name:"Property3",typeId:3},{name:"Property4",typeId:4}];
ko.subscribable.fn.subscribeChanged = function (callback, context) {
var savedValue = this.peek();
return this.subscribe(function (latestValue) {
var oldValue = savedValue;
savedValue = latestValue;
callback.call(context, latestValue, oldValue);
});
};
var DropDownItemViewModel = function (index){
var self = this;
self.SelectedValue = ko.observable();
self.Index = ko.observable(index);
self.Options = ko.observableArray(($.map(data, function (item) {
return new OptionItemViewModel(item);
})));
self.SelectedValue.subscribeChanged(function(newVal, oldValue){
if(newVal){
ko.utils.arrayForEach(appVM.MainPropertiesList(), function (item) {
ko.utils.arrayForEach(item.Options(), function (item2) {
if(item2 && item2.typeId() == newVal && self.Index() != item.Index() ){
item.Options.remove(item2);
if(oldValue){
item.Options.push(new OptionItemViewModel({name:"Property" + oldValue , typeId : oldValue}));
}
}
});
});
ko.utils.arrayForEach(appVM.SelectedPropertiesList(), function (item) {
if(item && item.typeId() == oldValue){
appVM.SelectedPropertiesList.remove(item);
}
});
appVM.SelectedPropertiesList.push(new OptionItemViewModel({name:"Property" + newVal , typeId : newVal}));
}
});
}
var OptionItemViewModel = function (data){
var self = this;
self.name = ko.observable(data.name);
self.typeId = ko.observable(data.typeId);
}
var AppViewModel = function(){
var self = this;
self.numberOfColumns = ko.observable(2);
self.properties = ko.observableArray();
self.MainPropertiesList = ko.observableArray();
self.SelectedPropertiesList = ko.observableArray();
for (var i = 0; i <= self.numberOfColumns(); i++) {
self.MainPropertiesList.push(new DropDownItemViewModel(i));
}
self.deleteColumn = function(item){
self.MainPropertiesList.remove(item);
self.UpdateDropDowns(item);
}
self.addColumn = function(){
self.MainPropertiesList.push(new DropDownItemViewModel(self.MainPropertiesList().length));
self.UpdateAddedDropDown();
}
self.UpdateAddedDropDown = function(){
var len = self.MainPropertiesList().length ;
ko.utils.arrayForEach(appVM.SelectedPropertiesList(), function (item) {
ko.utils.arrayForEach(self.MainPropertiesList()[len-1].Options(), function (item2) {
if(item && item2 && item.typeId() == item2.typeId()){
self.MainPropertiesList()[len-1].Options.remove(item2);
}
});
});
}
self.UpdateDropDowns = function(data){
if(data.SelectedValue()){
ko.utils.arrayForEach(self.MainPropertiesList(), function (item) {
item.Options.push(new OptionItemViewModel({name:"Property" + data.SelectedValue() ,typeId:data.SelectedValue()}));
});
}
}
}
var appVM = new AppViewModel();
ko.applyBindings(appVM);
相关文章:
- 根据路由URL设置select的值
- 如何在不触发更改事件的情况下设置 SELECT 元素的选定选项
- 使用JavaScript设置select标记的选定索引
- 根据json值设置select选项
- 使用jQuery设置Select Dropdown
- 在页面加载时设置select元素选项
- 不能从我的控制器中设置select value, Angular JS
- Knockout:在改变可观察数组后设置select的标题
- 如何在angular中设置select default选项?
- 使用AngularJS的双向数据绑定设置SELECT的默认值
- 如何使用angularjs-json数据设置select 2下拉列表的默认值
- 使用casperjs在表单上设置select
- 用KnockoutJS设置select的初始值
- 可以'当第一个select的值改变时,让jquery设置select输入的值
- 如何为嵌套的Mongoose文档设置select=false
- 如何设置select选项的默认值
- 使用Value属性设置Select的默认值
- 使用jQuery设置select后,无法使用jQuery获取select的选定值
- 如何在异步调用中使用敲除和typescript设置select的值
- 如何设置select语句的值