从 .ajax() 调用加载一个 knockout.js observableArray()

Posted

技术标签:

【中文标题】从 .ajax() 调用加载一个 knockout.js observableArray()【英文标题】:loading a knockout.js observableArray() from .ajax() call 【发布时间】:2012-04-01 14:18:57 【问题描述】:

这让我很困惑。它一定是我没看到的小东西。我正在尝试通过 ajax 调用在淘汰赛中加载一个非常简单的 observableArray

javascript

// we bind the array to the view model property with an empty array.
var data = [];   
var viewModel = 
    vendors: ko.observableArray(data)
;
ko.applyBindings(viewModel);

$(function () 
    // on this click event, we popular the observable array
    $('#load').click(function () 
        // WORKS. html is updated appropriately.
        viewModel.vendors([ "Id": "01" , "Id": "02" , "Id": "03" ]);

        // DOES NOT WORK. Fiddler2 shows the same exact json string come back 
        // as in the example above, and the success function is being called.
        $.ajax(
            url: '/vendors/10',
            dataType: 'json',
            success: function (data) 
                viewModel.vendors(data);
            
        );
    );
);

html

<button id="load">Load</button>
<ul data-bind="template:  foreach: vendors ">
    <li><span data-bind="text: Id"></span></li>
</ul>

问题:为什么ajax调用成功,谁的data变量值逐字节匹配硬类型值,而不触发html刷新?

【问题讨论】:

【参考方案1】:

没有理由这不能正常工作。如上所示。

http://jsfiddle.net/madcapnmckay/EYueU/

我会检查 ajax 帖子实际上是否返回了 json 数据,并且该 json 是一个数组并且它被正确解析。

我必须调整 ajax 调用以使 fiddle ajax 处理程序正常工作。

我想不出更多了。

希望这会有所帮助。

【讨论】:

感谢您验证我的理智......我会再仔细看看。也许 MVC 吸收了一个小包装器或其他东西...... 是的。 Firebug 请求响应,验证您正在获取 json,然后验证 jquery 正在将其解析为对象。 它肯定是 json...C# 代码看起来像 return Json(list, JsonResponseBehavior.AllowGet); 其中 list 是 ICollection` 所以我知道它是 JSON。除此之外,Fiddler2 正确地在其 JSON 视图中显示数据......它在某个地方的 javascript 中。明天上班时我会再次发布更多信息【参考方案2】:
var self=this;
//var self first line in model

$.ajax(
            url: ",
            dataType: "json",
            contentType: 'application/json',
            type: "POST",
            data: JSON.stringify( ),
            processdata: true,

            beforeSend: function () 
                $.mobile.loading('show');
            ,

            error: function (xhr, textStatus, errorThrown) 
                alert('Sorry!');
            ,

            success: function (data) 

                $.mobile.loading('hide');
                if (data.result!= '') 
                    self.vendors(data.result);



                 else 
                    self.vendors(something);

                
            
        );

使用 self.vendors 而不是这个 viewModel.vendors

【讨论】:

【参考方案3】:

这是我在 MVC .net 应用程序中使用 knout 和 jquery 所做的。

// Scripts/groItems.js
(function () 

    var ViewModel = function () 
        items = ko.observableArray(),
            ItemName = ko.observable(),
            Img = ko.observable(),
            Qty = ko.observable()
    

    $.getJSON('/Items2/AllItems', function (data) 
        for (var i = 0; i < data.length; i++) 
            self.items.push(data[i]);
        
    );

    var vm = new ViewModel();

    $(function () 
        ko.applyBindings(vm);
    );

());
@model IEnumerable<GroModel.Item>
@
    ViewBag.Title = "Index";


<p>
    @Html.ActionLink("Create New", "Create")
</p>

<div data-bind="text: items().length"></div>
<table class="container table table-hover">
    <thead>
        <tr>
            <th>Item name</th>
            <th>img</th>
            <th>qty</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: items">
        <tr>
            <td data-bind="text: ItemName"></td>
            <td data-bind="text: Img"></td>
            <td data-bind="text: Qty"></td>
        </tr>
    </tbody>
</table>

@section Scripts 
    <script src="~/Scripts/knockout-3.4.2.js"></script>
    <script src="~/Scripts/groItems.js"></script>

以下是我在 Items2Controller.cs 中的代码的一部分

    private GroContext db = new GroContext();
    public JsonResult AllItems()
    
        return Json(db.Items.ToList(), JsonRequestBehavior.AllowGet);
    

希望这会有所帮助。谢谢

【讨论】:

【参考方案4】:

我们可以使用一个简单的 JavaScript util 函数作为解决方法。

代替viewModel.vendors(data);,使用 eval 包装(首先研究 eval 的危险)会起作用。

eval("viewModel.vendors("+JSON.stringify(data)+");");

【讨论】:

不要使用 eval ***.com/questions/86513/…【参考方案5】:

我认为这是错误,当我们将 Knockout 的示例与包装类一起使用时,它正在工作:

public class ResultWrapper

    public Title get;set;
    public List<Result> get;set;

http://learn.knockoutjs.com/#/?tutorial=webmail

但是如果我们直接返回 Results 是没有办法绑定的。 (没有额外的 applyBindings!)

【讨论】:

以上是关于从 .ajax() 调用加载一个 knockout.js observableArray()的主要内容,如果未能解决你的问题,请参考以下文章

Knockout + MVC 禁用 html 按钮并在 ajax 调用后更改颜色

强制 Durandal 页面中的 Knockout 组件在绑定之前等待 Ajax 调用

Knockout ViewModel 在 ajax 之后被更新,但我的 foreach 没有被触发

在 knockout.js 中进行 ajax 检索后使字段可观察

在页面加载中默认调用更改事件 - 淘汰赛

异步加载Knockout组件中的模板