1

In my ViewModel for my MVC4 application I have some code to get names from an ajax call and populate a simple control within my page, which is using Bootstrap 3. As you can see below I have a hard-coded array which works perfectly. With the ajax call, I see the data in the UI but it does not update my control and I have NO idea why. I have verified the data exists and I have also tried setting self.Names = ko.observableArray within the ajax call. Is there a simple reason why? As I said I see the data within my form in both scenarios but I am not seeing the update I expect.

$(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);
});

Here is the Response from the body via the ajax call:

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

My 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>
4

1 回答 1

0

可能是因为传入的数据的结构与您的绑定不同,或者未正确设置/更新可观察对象。如果没有观察到它们,那么它们将不会更新。

我对此不是 100% 确定的,但我认为您必须使用可观察数组函数才能让观察者(绑定到数组或其内容的 UI 元素)实际得到更新。基于淘汰赛网站上可观察数组文档中的一部分:

2.对于修改数组内容的函数,比如push和splice,KO的方法会自动触发依赖跟踪机制,这样所有注册的监听器都会收到变化通知,你的UI会自动更新。

根据 json,您可以解决此问题的一种方法是清除 observable 数组并使用转换为 observable 的数据元素重新加载它:

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());}
于 2014-03-07T17:10:49.037 回答