2014-01-15 44 views
3

我想选择一个默认选择选项,基于我填充我的选择选项的属性之一。选择默认选项值与淘汰赛

此代码直接从@rneimeyer's fiddle复制。我做了调整,做我想做的事情。

所以,我有选择作为我的observableArray。

var choices = [ 
    { id: 1, name: "one", choice: false }, 
    { id: 2, name: "two", choice: true }, 
    { id: 3, name: "three", choice: false } 
    ]; 

function ViewModel(choices, choice) { 
    this.choices = ko.observableArray(choices); 
}; 

rneimeyer的小提琴和矿山之间的区别是,我将我的对象上choice财产observableArray内,而不必为我们想成为默认选项单独观察到。

这是我的尝试fiddle

现在我在选择元素标记中检查choice属性是否为true。如果是,那么我想将name设置为value属性,以使其成为默认值。

<select data-bind="options: choices, optionsText: 'name', value: choice"></select> 

我已经与simple data model in my fiddle这里还有这是工作只是因为我想测试此。

我想我真正的疑问是如何检查choice属性在数据绑定。我发现optionText能够正常访问name属性。不知道为什么value属性中的choice属性不相同。

+1

' rneimeyer的小提琴与我的区别在于,我在observableArray中的对象上添加了choice属性,而不是为我们想要默认的选项设置单独的observable。“为什么?另一种方法有什么问题?你想通过这样做来解决什么问题? –

+0

不同之处在于数据如何通过服务传递给我。该服务将一个块中的所有信息提供给我,而不是仅具有默认选项的对象。 – shriek

+0

那么?当你从你的服务中获得数据时,你通过它运行并取出具有'choice === true'的数据并放入你的'selectedOption'可观察数据中。就目前而言,它不会起作用,因为“选择”无论如何都不是可观察的,而且您有问题,因为您无法一次更改两个条目中的“选择”,所以您将会遇到两种选择选择或不选择选项。 –

回答

7

我可能会误导一些人。另外,我很抱歉没有提及我使用的版本。我目前正在使用Knockout 3.0.0(你会明白为什么这个很重要)

此外,只是要说明,我不是说@ XGreen的方法是错误的,但那不是我正在寻找因为这可能是由于我的糟糕解释。

让我先试着澄清一下我试图完成的事情。 首先,我将拥有一个包含选项信息的对象数组。现在

[ 
{ id: 1, name: "one", choice: false }, 
{ id: 2, name: "two", choice: true }, 
{ id: 3, name: "three", choice: false } 
] 

,我想要做的是数据绑定选择选项到阵列的选择真的是默认选择之一。

我不打算创建任何额外的observable,除了数组本身,这将是一个observableArray。

经过多番研究,我终于找到optionsAfterRender属性options属性。

<select data-bind="options: choices, 
        optionsValue: 'name', 
        optionsAfterRender: $root.selectDefault"> 
</select> 

那么optionsAfterRender确实是,每个数组元素调用它,我已经设置检查是否choice是真的还是假的,并选择选项,其中有真正的价值自定义函数。

请注意,ko.applyBindingsToNode不是工作在我原来的小提琴中的版本2.2.0。

function ViewModel(choices) { 
    this.choices = ko.observableArray(choices); 
    this.selectDefault = function(option,item){ 
     if(item.choice){ 
      ko.applyBindingsToNode(option.parentElement, {value: item.name}, item); 
     } 
    }; 
}; 
ko.applyBindings(new ViewModel(choices)); 

而这里是它的fiddle

+1

不错的工作。请记住,在您的解决方案中,您的集合中始终有最后一个元素,它的选择属性是默认值。如果您在任何时候都只有一件物品是真的,这并不重要,但是对于较大的集合和很多真实的物品,这可能是一个浪费的迭代,因为您可能已经放弃寻找第一个真实物品 – XGreen

+0

非常好的一点冗余迭代。 – shriek

2

好吧如果我明白你想设置真正的选择作为你的默认选择值。

首先,你需要涉及您的下降id下来,它成为期权的价值,我们将基于这一独特id

<select data-bind="options: choices, optionsText: 'name', optionsValue: 'id', value: selectedChoice"></select> 

筛选我们收集正如你现在看你需要创建一个新的可观察的,称为selectedChoice,我们将使用计算结果填充该可观测值。

var choices = [ 
    { id: 1, name: "one", choice: false }, 
    { id: 2, name: "two", choice: true }, 
    { id: 3, name: "three", choice: false } 
    ]; 

function ViewModel(choices) { 
    var self = this; 
    self.choices = ko.observableArray(choices); 
    self.trueChoice = ko.computed(function(){ 
     return ko.utils.arrayFirst(self.choices(), function(item){ 
      return item.choice === true; 
     }); 
    }); 
    self.selectedChoice = ko.observable(self.trueChoice().id); 
}; 

ko.applyBindings(new ViewModel(choices)); 

新计算财产trueChoice使用arrayFirst方法,以便在您选择的集合,有其选择的属性设置为true,返回的第一个项目。

现在我们有了我们真正的选择,我们所要做的就是将选择的下拉列表的值012xx设置为真正的选择的标识,以便在下拉菜单中选择该项目。

Here is also a working fiddle for this

+0

你是对的,需要'optionsValue'。这是这件作品的关键部分,但我仍然不打算在我的虚拟机上创建可观察性,只是对选择选项进行简单检查。 – shriek

0

您可以创建一个计算保存所选项目

self.selected_options = ko.computed({ 
    read: function() { 
     return self.choices.filter(function(item){ return item.choice }); 
    }, 
    write: function(value) { 
     self.choices.forEach(function(item) { item.choice = value.indexOf(item) > 0;}); 
    } 
}) 

然后绑定到作为选择的选项。

2

补充说,禁止在下拉列表中选择第一个选项,并有很好的工作要点KO的optionsCaption绑定,使用optionsDisableDefault绑定:

https://gist.github.com/garrypas/d2e72a54162787aca345e9ce35713f1f

HTML:

<select data-bind="value: MyValueField, 
    options:OptionsList, 
    optionsText: 'name', 
    optionsValue: 'value', 
    optionsCaption: 'Select an option', 
    optionsDisableDefault: true"> 
</select> 
+0

像魅力一样工作 – user2475096