在我的应用程序中,我试图将bootstrap和knockout集成到MVC4中。我有两个下拉控件,用户可以从中选择一个项目,然后我使用jQuery填充旁边的文本框。当我使用ViewBag和@foreach循环时,这没有问题,但是当我尝试使用knockout observable时,我遇到了问题。
我能够看到我的ViewModel中的数据显示在下拉控件中,但它不会在文本框中更新该值。我应该使用特殊的数据绑定属性吗?
一些代码......
<div class="container">
<div class="col-sm-7 well">
<form class="form-inline" action="#" method="get">
<div class="input-group col-sm-8">
<input class="form-control" value="" placeholder="Work Section" name="q" type="text">
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Select <span class="caret"></span></button>
<ul class="dropdown-menu">
<li data-bind="foreach: Names">
<a href="#" data-bind="text: Name, value: Name"></a>
</li>
</ul>
<input name="category" class="category" type="hidden">
</div>
</div>
<div class="input-group col-sm-8">
<input class="form-control item" value="" placeholder="Select a Color" name="color" type="text">
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle item" data-toggle="dropdown">Select <span class="caret"></span></button>
<ul class="dropdown-menu">
@foreach (var item in ViewBag.Colors)
{
<li>
<a href="#">@item</a>
</li>
}
</ul>
<input name="category" class="category" type="hidden">
</div>
</div>
问题出在Names foreach上,因为Colors正常工作。
我正在使用它来查找页面上的控件并获取所选项目并将其放在输入控件中...我已经验证了这一点现在只适用于颜色下拉列表。
$(function () {
$(".dropdown-menu li a").click(function () {
$(this).parents(".input-group").find('.form-control').text($(this).text());
$(this).parents(".input-group").find('.form-control').val($(this).text());
});
});
我尝试过以下两种方法都无济于事。让我们从第一个回应开始......
我将以下内容放在页面顶部的标签中
$(function ViewModel() {
alert('Here'); // To test if the code generating the model is executed
this.Names = [{ name: "Person 1", name: "Person 2" }];
this.selectedName = ko.observable();
this.clickName = function (name) { this.selectedName = name; }
});
接下来,我在页面顶部放置了一个新内容:
<p>Current selection is <span data-bind="text: selectedName"></span></p>
最后,我将此代码放在bootstrap下拉列表中:
<ul class="dropdown-menu" data-bind="foreach: Names">
<li class="dropdown">
<a href="#" data-bind="text: Name, value: Name, click: clickName(Name)"></a>
</li>
</ul>
下拉列表为空,div永远不会更新。
好的,在我创建了ViewModel并集成了click:function(){$ root.Name(Name);}后,我现在可以看到我的值更新了。
这是我的视图模型代码
$(document).ready(function () {
function ViewModel() {
var self = this;
self.Name = ko.observable("");
var Names = {
Name: self.Name
};
self.Name = ko.observable();
self.Names = ko.observableArray([{ Name: "Brian" }, { Name: "Jesse" }, {Name: "James"}]);
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
});
答案 0 :(得分:1)
Bootstrap创建的下拉菜单并不是真正的控件,它只是花哨的CSS。因此,需要手动处理Bootstrap下拉选择。这是Knockout 真正帮助的地方。
因此,基于上面的代码,我创建了一个简单的jsFiddle。
下拉列表与此类似(请注意foreach
绑定的位置与问题中的示例不同,位于ul
而不是li
):
<ul class="dropdown-menu" data-bind="foreach: Names">
<li class="dropdown">
<a href="#" data-bind="text: Name, value: Name, click: function() {$root.selectedName(Name);}"></a>
</li>
</ul>
这假定视图模型类似于:
var ViewModel = function() {
var self = this;
//Properties
self.selectedName = ko.observable("NONE");
self.Names = ko.observableArray([
{ Name:"Name1" },
{ Name:"Name2" },
{ Name:"Name3" },
]);
}
因此,通过使用click
绑定,可以将用户选择反馈回Knockout视图模型。当然,代替视图中的函数(function() {$root.selectedName(Name);}
位),理想情况下它应该是方法ViewModel
,但我认为首先以这种方式显示它更清楚。
答案 1 :(得分:1)
假设您的视图模型目前看起来像
function ViewModel() {
this.Names = [{name: x}, ...];
}
你应该扩展如下
function ViewModel() {
this.Names = [{name: x}, ...];
this.selectedName = ko.observable();
this.clickName = function(name) { this.selectedName(name); }
}
然后,您可以在文本字段上添加data-bind="text: selectedName"
,在链接上添加data-bind="click: clickName(Name)"
。不需要jQuery选择器,因此您可以将数据交互与DOM结构分离。