【问题标题】:Knockout.js databinding to ViewModelKnockout.js 数据绑定到 ViewModel
【发布时间】:2023-03-15 14:29:01
【问题描述】:

我正在努力了解 KnockOut 数据绑定,并且我正在努力获得一个简单的表单来绑定到我的 ViewModel。

我正在使用 WebAPI 拉回我的 JSON 数据。

这是我的 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>

这是我尝试将 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>

我尝试过查看各种binding-contexts,但似乎没有一个可以解决问题。如果我在 WorkOrderViewModel 中设置(例如)self.DistrictCode,我可以让它工作,但这不是我想要做的。

我是否遗漏了一些非常明显的东西?

编辑:我有点接近了,如果我添加到 WorkOrderViewModel 中,它会绑定。在 Ajax 调用之后仍然不会更新...

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

self.WorkOrder = new WorkOrder(DummyWorkOrder);

【问题讨论】:

    标签: javascript knockout.js asp.net-web-api


    【解决方案1】:

    DistrictCodeWorkOrderNumber 不是实时数据绑定所需的 ko.observable 的实例(基于您问题中的代码 sn-p)。尝试使用 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);
        }
    

    另请注意,Artem 建议的 with: WorkOrder 绑定也是您的标记工作所必需的。这是因为DistrictCodeWorkOrderNumberWorkOrderDescription 没有直接被WorkOrderViewModel 暴露。每个绑定路径都必须通过视图模型上的WorkOrder 属性。

    【讨论】:

    • 感谢您的关注,但仍然没有骰子。真的很奇怪,似乎在 Ajax 调用之后它不会更新(我已经更新了我的问题)。
    • 何时调用find?有什么办法可以把它放在小提琴里吗?
    【解决方案2】:

    您是在ko.applyBindings 之前还是之后打电话给self.Find?如果你在之后调用它,那么这就是你的问题。

    如果self.WorkOrder 只是一个对象,那么它将是单向绑定。除非您强制 DOM 刷新/重新绑定,否则对它的任何更新都不会更新 DOM(请注意,来自 DOM 的任何更新都不会反映在绑定对象中)。如果self.WorkOrder 是一个可观察对象,您将用self.WorkOrder = new WorkOrder(data); 覆盖它您需要更新可观察对象:self.WorkOrder(new WorkOrder(data));

    【讨论】:

    • 谢谢!这让我很头疼,需要初始化绑定并使其成为可观察的,您建议的更改一切正常。
    猜你喜欢
    • 2012-06-16
    • 2012-10-27
    • 2014-05-12
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 2015-06-08
    • 1970-01-01
    • 2014-07-30
    相关资源
    最近更新 更多