【问题标题】:data-bind issue with knockout 3淘汰赛 3 的数据绑定问题
【发布时间】:2014-04-09 23:12:44
【问题描述】:

在我的应用程序中,我试图将引导程序和淘汰赛集成到 MVC4 中。我有两个下拉控件,用户可以从中选择一个项目,然后我使用 jQuery 填充旁边的文本框。当我使用 ViewBag 和 @foreach 循环时,这没有问题,但是当我尝试使用淘汰赛 observables 时,我遇到了问题。

我可以看到来自我的 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>

问题在于名称 foreach,因为颜色工作正常。

我正在使用它来查找页面上的控件并获取所选项目并将其放置在输入控件中...我已经验证这现在仅适用于颜色下拉菜单。

$(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>

最后,我将这段代码放在引导下拉菜单中:

<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 并集成点击后: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);
});

【问题讨论】:

  • 我尝试了上面的方法并修改了我上面的代码,请看一下。

标签: jquery asp.net-mvc-4 twitter-bootstrap-3 knockout-3.0


【解决方案1】:

Bootstrap 创建的下拉菜单本身并不是真正的控件,它只是花哨的 CSS。因此,需要手动处理 Bootstrap 下拉选择。这就是淘汰赛真正有帮助的地方。

所以根据您上面的代码,我创建了一个简单的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,但我认为首先以这种方式显示会更清楚。

【讨论】:

  • 嗨,马特,感谢您的回复。我尝试了您的建议,但出现以下错误:未捕获的 TypeError:无法读取 null 的属性“nodeType”。通常我通过将我的 javascript 放在 $(function (){}); 中来解决这个问题。但是当我这样做时,我得到一个不同的错误,说明我的 viewModel 没有定义。我们越来越近了:-)
  • 希望 Fiddle 中的工作示例能够帮助您实现目标。如果不是,可能值得问另一个问题。如果您愿意,请在此处将其链接到评论中。
【解决方案2】:

假设你的视图模型当前看起来像

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 结构分离。

【讨论】:

  • 感谢您的帮助。上面来自马特的解决方案更接近我所需要的。我无法让您的解决方案在 JSFiddle 中工作,但这与我缺乏知识有关。
  • 我意识到我的解决方案有一个错误——我的解决方案和马特的解决方案几乎相同(这是最基本的 KO 用例之一),除了他在视图模型中使用匿名函数而不是命名函数点击事件。
猜你喜欢
  • 2013-10-08
  • 1970-01-01
  • 2014-09-18
  • 1970-01-01
  • 2012-12-22
  • 2013-03-06
  • 2016-11-06
  • 1970-01-01
相关资源
最近更新 更多