Knockout可观察数组

时间:2014-03-07 17:02:14

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

在我的MVC4应用程序的ViewModel中,我有一些代码从ajax调用中获取名称并在我的页面中填充一个简单的控件,这是使用Bootstrap 3.如下所示,我有一个硬编码的数组,它可以工作完美。使用ajax调用,我在UI中看到了数据,但它没有更新我的控件,我不明白为什么。我已验证数据存在,我也尝试在ajax调用中设置self.Names = ko.observableArray。有一个简单的原因吗?正如我所说,我在两种情况下都看到了表单中的数据,但我没有看到我期望的更新。

$(document).ready(function () {
    function ViewModel() {

        //Make the self as 'this' reference
        var self = this;
        //Declare observable which will be bind with UI
        self.Name = ko.observable("");

        var Names = {
            Name: self.Name
        };

        self.Name = ko.observable();
        //self.Names = ko.observableArray([{ Name: "Brian" }, { Name: "Jesse" }, { Name: "James" }]);
        self.Names = ko.observableArray();   // Contains the list of Names

        // Initialize the view-model
        $.ajax({
            url: '@Url.Action("GetNames", "Home")',
            cache: false,
            type: 'GET',
            contentType: 'application/json; charset=utf-8',
            data: {},
            success: function (data) {
                self.Names(data); //Put the response in ObservableArray
            }
        });
    }

    var viewModel = new ViewModel();
    ko.applyBindings(viewModel);
});

这是身体通过ajax调用的响应:

[{"Id":1,"Name":"Brian"},{"Id":2,"Name":"Jesse"},{"Id":3,"Name":"James"}] 

我的HTML

<p>Current selection is <span data-bind="text:Name"></span></p>
<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" 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" data-bind="foreach: Names">
                        <li class="dropdown">
                            <a href="#" data-bind="text: Name, value: Name, click: function() {$root.Name(Name);}"></a>
                        </li>
                    </ul>
                    <input name="category" class="category" type="hidden">
                </div>
            </div>

1 个答案:

答案 0 :(得分:0)

可能是因为进入的数据结构与结构不相同,或者未正确设置/更新可观察数据。如果没有观察到它们就会更新。

我对此并不是100%肯定,但我认为你必须使用可观察数组函数才能使观察者(绑定到数组或其内容的UI元素)实际更新。基于observable array documentation on the knockout site

的一个部分
  

2.对于修改数组内容的函数,如push和splice,KO的方法会自动触发依赖关系跟踪   机制,以便所有注册的听众都收到通知,   并且您的UI会自动更新。

根据json,你可以解决这个问题的一种方法是清除可观察数组并用转换为observables的数据元素重新加载它:

self.Names.removeAll();
var newName = null;
for (var idx = 0; idx < data.length; idx++) {
    newName = data[idx];
    newName.Id = ko.observable(newName.Id);
    newName.Name = ko.observable(newName.Name);
    self.Names.push(newName);
}

在你的HTML上。 click函数使用所选数组元素的Name属性作为参数。你不想要这个,你想要最新的价值。所以改变这个:

click: function() {$root.Name(Name);}

到这个

//notice the new parenthesis after Name.
click: function() {$root.Name(Name());}