2

我正在使用 KnockoutJS 进行数据绑定。以下代码是控制器的操作方法

public JsonResult GetPeople()
{
    var people = new List<Person>
                     {
                         new Person {Name = "aaaa", Address = "aaaaaaaaa"},
                         new Person {Name = "bbbb", Address = "bbbbbbbbb"},
                         new Person {Name = "cccc", Address = "ccccccccc"}
                     };
    return Json(people, JsonRequestBehavior.AllowGet);
}

下面是客户端代码片段

<ul data-bind="foreach: people">
  <li>NAME:<span data-bind="text: Name"></span></li>
  <li>ADDRESS:<span data-bind="text: Address"></span></li>  
</ul>

<script>
    function getPeopleFromServer() {
        var people= [];

        $.ajax({
            url: "GetPeople",
            cache: false,
            type: "GET",
            success: function (result) {
                console.log("result= " + result);
                people = $.parseJSON(result);
                console.log("people= " + people);
            }
        });

        return people;
    }

    function ViewModel() {
        var self = this;

        // data
        self.people = ko.observableArray(getPeopleFromServer());        
    }

    ko.applyBindings(new ViewModel());
</script>

问题是 getPeopleFromServer 方法中的 people 变量始终为 null,而 result 具有来自服务器的正确值。我错过了什么吗?

4

4 回答 4

1

您的$.ajax函数比它的包含函数花费更长的时间来完成,因此包含函数永远不会people在执行结束时弹出

您可以做的一件事是将以下内容添加到您的$.ajax:

$.ajax({
   async: false,
   url: "GetPeople",
   .....
});

async: false将使包含函数“等待”直到 ajax 完成。您的人员变量应在函数执行结束时填充。虽然这是一个快速的胜利,但我同意Tom的观点,即您应该重新考虑如何处理您的 ViewModel。

于 2012-05-17T02:26:08.437 回答
0

人们应该在同一个视图模型中被引用。或者作为self.people。我建议你把对 ajax 的调用放在视图模型中,然后就清楚了。所以 getPeopleFromServer() 应该在视图模型中。

出于兴趣,您还可以添加 timeout: 600000 以便呼叫不会超时。

于 2012-05-17T12:49:56.227 回答
0

@tom 的评论是正确的。

'success' 是一个内联异步函数。基本上,'return people' 发生在调用 'success' 函数之前,因为 ajax 调用是非阻塞的。您需要重新设计您的 ViewModel 以异步工作(或关闭异步),希望其他人会加入代码修复

这是他预言的完整评论的小提琴。

http://jsfiddle.net/bczengel/8Wqum/

于 2012-05-20T02:20:39.507 回答
0

尝试使用 ko.mapping 插件。

function ViewModelWrapper(jsonResult)
{
       var self = this;
       self.model = ko.mapping.fromJS(jsonResult);
}

http://knockoutjs.com/documentation/plugins-mapping.html

于 2012-05-17T13:13:21.987 回答