来自JSON文件问题的Knockout绑定

时间:2016-10-09 19:36:58

标签: javascript mvvm knockout.js

我正在使用Typescript来定义我的Knockout ViewModel。

我有一个JSON文件,其结构可以看到here(Github gist因为它在这里粘贴有点大)。

结构基本上是:

OrderLine(根) - >里程碑 - > factory_date

或口头:(很多)订单行有(很多)里程碑,每个里程碑都有(一个)工厂日期。

我正在尝试使用以下内容构建ViewMOdel:

var FactoryAppViewModel = (function () {
function FactoryAppViewModel(seasonID) {
    var self = this;
    self.seasonID = seasonID;
    self.orderlines = ko.observableArray([]);
    this.buildViewModel();
}

FactoryAppViewModel.prototype.buildViewModel = function () {
    var self = this;
    var getOrderLines = HTTP.get("/season/" + self.seasonID + "/orderlines").done(function (data) {
        self.orderlines(JSON.parse(data));
    }).fail(function () {
        error("Could not get orderlines");
    });
};

据我所知,此处数据的JSON.parse会将值应用于订单行ko.observableArray([]),但我需要将ko.observable应用于订单行子项(里程碑),以及里程碑孩子(factory_date)。我不知道该怎么做。至少来自JSON。

我已阅读this,但似乎没有帮助我。

我知道observable未应用,因为当我在视图中更改factory_date时,它不会更新视图模型。

任何帮助将不胜感激。上面的javascript是已编译的TypeScript。

编辑:

以下是我在视图中访问代码的方式示例:

<tbody data-bind="foreach: orderlines">
        <tr>
            <td data-bind="text: factory.name"></td>
            <!-- ko foreach: milestones -->
                <!-- ko if: factory_date == null -->
                    <td>
                        <span>TBA</span>
                    </td>
                <!-- /ko -->
                <!-- ko if: factory_date !== null -->
                    <td>
                        <div class="wrapper-wrapper">
                            <div class="btn btn-primary dateChanger">
                                <span data-bind="text: moment(factory_date.milestone_date).format('DD-MM-YYYY')"></span>
                            </div>
                            <div class="date-update-wrapper text-center">
                                <input type="text" data-bind="attr: {value: moment(factory_date.milestone_date).format('DD-MM-YYYY')}" class="form-control datetimepicker">
                                <a class="save-date btn btn-success" data-bind="click: function(){$root.saveDate(factory_date, $parent)}"><i class="fa fa-check"></i></a>
                                <a class="cancel-date btn btn-danger"><i class="fa fa-times"></i></a>
                            </div>
                        </div>
                    </td>
                <!-- /ko -->
            <!-- /ko -->
        </tr>
    </tbody>

让我意识到我遇到问题的部分是这部分:

data-bind="click: function(){$root.saveDate(factory_date, $parent)}"

我创建了一个简单的saveDate方法,它是console.log(factory_date.milestone_date),它返回了默认的JSON数据,尽管我在视图中对其进行了编辑(使用了datepicker)。

1 个答案:

答案 0 :(得分:0)

默认情况下,Knockout不会将列表中的子项映射到observable。有一个名为ko.mapping的插件可以帮助您实现所需的目标。

你可以设置一个孩子&#34;映射,或循环遍历您的孩子,手动使它们可观察(在这种情况下来自JavaScript):

&#13;
&#13;
var mappedChildren = [];
var children = someObj.children();
for (var i = 0; i < children.length; i++) {
  var mappedChild = ko.mapping.fromJS(children[i], mappingFunction);
  mappedChildren.push(mappedChild);
}
someObj.children(mappedChildren);
&#13;
&#13;
&#13;