简体   繁体   English

Knockout.js数据绑定到ViewModel

[英]Knockout.js databinding to ViewModel

I'm trying to get my head around KnockOut data bindings and I'm struggling to get a simple form to bind to my ViewModel. 我试图了解KnockOut数据绑定,并且正在努力获取一个简单的表单来绑定到ViewModel。

I'm using WebAPI to pull back my JSON data. 我正在使用WebAPI提取我的JSON数据。

This is my ViewModel, once this 'find' method has been called it creates a new WorkOrder object and populates some properties (I've tested this and it's definitely setting these values). 这是我的ViewModel,一旦调用了该“查找”方法,它就会创建一个新的WorkOrder对象并填充一些属性(我已经对此进行了测试,并且肯定会设置这些值)。

<script type="text/javascript">

    function WorkOrder(workOrder) {
        var self = this;

        self.DistrictCode = workOrder.DistrictCode;
        self.WorkOrderNumber = workOrder.WorkOrderNumber;
        self.WorkOrderDescription = ko.observable(workOrder.WorkOrderDescription);
    }

    var apiUrl = 'api/workorders';

    function WorkOrderViewModel() {
        var self = this;

        self.find = function() {
            var id = $('#workOrderNumber').val();
            $.getJSON(apiUrl + '/' + id)
                .done(function(data) {
                    self.WorkOrder = new WorkOrder(data);
                })
                .fail(function(jqXHR, textStatus, err) {
                    $('#workorder').text('Error: ' + err);
                });
        }
    }

    $(document).ready(function() {
        ko.applyBindings(WorkOrderViewModel());
    });

</script>

This is my HTML code where I'm trying to bind the WorkOrder class to: 这是我试图将WorkOrder类绑定到的HTML代码:

<h2>Work Order Details</h2>
<table>
    <tr>
        <td>
            District Code:  
        </td>
        <td>
            <input data-bind="value: DistrictCode"/>
        </td>
    </tr>
    <tr>
        <td>
            Work Order Number:  
        </td>
        <td>
            <input data-bind="value: WorkOrderNumber"/>
        </td>
    </tr>
    <tr>
        <td>
            Work Order Description:  
        </td>
        <td>
            <input data-bind="value: WorkOrderDescription"/>
        </td>
    </tr>
</table>

I've tried looking at the various binding-contexts but none seem to do the trick. 我尝试查看各种绑定上下文,但是似乎没有一个可行的方法。 I can get it to work if I set (for example) self.DistrictCode in WorkOrderViewModel but this isn't what I want to do. 如果在WorkOrderViewModel中设置(例如)self.DistrictCode,我可以使它工作,但这不是我想要的。

Am I missing something really obvious? 我是否真的缺少明显的东西?

Edit : I've got a little bit closer, if I add into WorkOrderViewModel, it binds. 编辑 :我有点接近,如果我添加到WorkOrderViewModel,它将绑定。 Still won't update after the Ajax call though... 仍然不会在Ajax调用后更新...

var DummyWorkOrder = { DistrictCode: "XXX", WorkOrderNumber: "1234560", WorkOrderDescription: "My Description" };

self.WorkOrder = new WorkOrder(DummyWorkOrder);

Are you calling self.Find before or after the ko.applyBindings ? 您是在self.Find之前还是之后打电话给ko.applyBindings吗? If you're calling it after, then this is your problem. 如果您在之后调用它,那么这就是您的问题。

If self.WorkOrder is just an object, then it will be a one way binding. 如果self.WorkOrder只是一个对象,那么它将是一种单向绑定。 Any updates to it won't update the DOM unless you force the DOM to refresh/rebind (and note that any updates from the DOM will not be reflected in the bound object). 对其进行的任何更新都不会更新DOM,除非您强制DOM刷新/重新绑定(请注意,来自DOM的任何更新都不会反映在绑定对象中)。 If self.WorkOrder is an observable, you're overwriting it with self.WorkOrder = new WorkOrder(data); 如果self.WorkOrder是可观察的,则您将用self.WorkOrder = new WorkOrder(data);覆盖它self.WorkOrder = new WorkOrder(data); You need to update the observable: self.WorkOrder(new WorkOrder(data)); 您需要更新可观察对象: self.WorkOrder(new WorkOrder(data));

DistrictCode and WorkOrderNumber aren't instances of ko.observable which is required for real-time data-binding (based on the code snippet in your question). 实时数据绑定(基于您问题中的代码段)不是必需的DistrictCodeWorkOrderNumber实例的ko.observable实例。 Try updating your WorkOrder constructor with observables: 尝试使用可观察对象更新您的WorkOrder构造函数:

function WorkOrder(workOrder) {
        var self = this;

        self.DistrictCode = ko.observable(workOrder.DistrictCode);
        self.WorkOrderNumber = ko.observable(workOrder.WorkOrderNumber);
        self.WorkOrderDescription = ko.observable(workOrder.WorkOrderDescription);
    }

Also note that the with: WorkOrder binding suggested by Artem would also be required for your markup to work. 还要注意,Artem建议的with: WorkOrder绑定也需要标记才能起作用。 This is because DistrictCode , WorkOrderNumber and WorkOrderDescription aren't exposed by the WorkOrderViewModel directly. 这是因为DistrictCodeWorkOrderNumberWorkOrderDescription不被暴露WorkOrderViewModel直接。 The binding path for each must go through the WorkOrder property on your view model. 每个对象的绑定路径都必须通过视图模型上的WorkOrder属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM