使用knockout,我有一个select(一个名字列表),其选项绑定到另一组敲除数据(人)。当任何人的姓名更改时,绑定到该人姓名的选择选项的值将正确更新。但是,如果您已选择该人,则不会保留选择的选择。
请参阅此jsFiddle以获取实例:http://jsfiddle.net/DbBZQ/
即使基础值发生了变化,如何使选择保持相同的选项索引?有没有办法指示淘汰赛保留选择,还是我必须使用JS单独执行此操作?
完整代码示例
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-2.2.1.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
var data =
{
people: ko.observableArray(
[
{ name: ko.observable("Jim") },
{ name: ko.observable("Jane") },
{
name: ko.observable("Sam"),
subordinates: ko.observableArray(
[
{
name: ko.observable("Tambone"),
subordinates: ko.observableArray(
[
{ name: ko.observable("Edward") },
{ name: ko.observable("Kristy") },
{ name: ko.observable("Thomas") },
{ name: ko.observable("Andy") }
])
},
{ name: ko.observable("Jules") }
])
}
])
};
var allNames = ko.computed(function ()
{
var names = [];
var selector = function (name, indent)
{
var option =
{
value: name,
text: (indent || "") + name
};
return option;
};
for (var i = 0; i < data.people().length; i++)
{
names.push(selector(data.people()[i].name()));
addSubordinates(names, 1, data.people()[i].subordinates, selector);
}
return names;
});
function addSubordinates(names, depth, subordinates, selector)
{
if (subordinates != null)
{
var indentText = "";
for (var i = 0; i < depth; i++)
indentText += ". . ";
for (var i = 0; i < subordinates().length; i++)
{
names.push(selector(subordinates()[i].name(), indentText));
addSubordinates(names, depth + 1, subordinates()[i].subordinates, selector);
}
}
}
</script>
</head>
<body>
<div data-bind="foreach: data.people">
<input type="text" data-bind="value: name" /><br />
</div>
<a href="JavaScript:data.people.push({ name: ko.observable('New Person') });">Add Person</a>
<br /><br /><br />
<select data-bind="options: allNames, optionsValue: 'value', optionsText: 'text', optionsCaption: 'All Names...'" />
<script type="text/javascript">
ko.applyBindings();
</script>
</body>
</html>
答案 0 :(得分:1)
选择丢失的原因是因为所选值直接与name属性匹配,而name属性会发生变化。因此,数据源(allNames)中不再存在所选值。
如果您想保留选择,您有几个选择:
您是否拥有可用作所选值的不可变属性?
为了举例,我在数据源中的对象中添加了一个id属性,并将其用作选定的值而不是name。这符合您的预期:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-2.2.1.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
var data =
{
people: ko.observableArray(
[
{ id: 1, name: ko.observable("Jim") },
{ id: 2, name: ko.observable("Jane") },
{
id: 3, name: ko.observable("Sam"),
subordinates: ko.observableArray(
[
{
id: 4, name: ko.observable("Tambone"),
subordinates: ko.observableArray(
[
{ id: 5, name: ko.observable("Edward") },
{ id: 6, name: ko.observable("Kristy") },
{ id: 7, name: ko.observable("Thomas") },
{ id: 8, name: ko.observable("Andy") }
])
},
{ id: 9, name: ko.observable("Jules") }
])
}
])
};
var allNames = ko.computed(function ()
{
var names = [];
var selector = function (id, name, indent)
{
var option =
{
value: id,
text: (indent || "") + name
};
return option;
};
for (var i = 0; i < data.people().length; i++)
{
names.push(selector(data.people()[i].id, data.people()[i].name()));
addSubordinates(names, 1, data.people()[i].subordinates, selector);
}
return names;
});
function addSubordinates(names, depth, subordinates, selector)
{
if (subordinates != null)
{
var indentText = "";
for (var i = 0; i < depth; i++)
indentText += ". . ";
for (var i = 0; i < subordinates().length; i++)
{
names.push(selector(subordinates()[i].id,subordinates()[i].name(), indentText));
addSubordinates(names, depth + 1, subordinates()[i].subordinates, selector);
}
}
}
</script>
</head>
<body>
<div data-bind="foreach: data.people">
<input type="text" data-bind="value: name" /><br />
</div>
<a href="JavaScript:data.people.push({ name: ko.observable('New Person') });">Add Person</a>
<br /><br /><br />
<select data-bind="options: allNames, optionsValue: 'value', optionsText: 'text', optionsCaption: 'All Names...'" />
<script type="text/javascript">
ko.applyBindings();
</script>
</body>
</html>
修改强>
作为替代方案,如果您设置value
属性以使其为返回项目索引的ko.computed,该怎么办?像这样:
var allNames = ko.computed(function ()
{
var names = [];
var selector = function (item, name, indent)
{
var option =
{
value: ko.computed(function(){ return data.people().indexOf(item);}),
text: (indent || "") + name
};
return option;
};
for (var i = 0; i < data.people().length; i++)
{
names.push(selector(data.people()[i], data.people()[i].name()));
addSubordinates(names, 1, data.people()[i].subordinates, selector);
}
return names;
});
function addSubordinates(names, depth, subordinates, selector)
{
if (subordinates != null)
{
var indentText = "";
for (var i = 0; i < depth; i++)
indentText += ". . ";
for (var i = 0; i < subordinates().length; i++)
{
names.push(selector(subordinates()[i],subordinates()[i].name(), indentText));
addSubordinates(names, depth + 1, subordinates()[i].subordinates, selector);
}
}
}