0

我试图了解如何将数据从视图模型绑定到视图。REST对后端的请求工作正常,我得到一个包含多个项目的 JSON 数组。现有的文档没有给我足够的帮助。

如何将时间线组件绑定ojtimeline到视图模型数据数组?

编辑:现在没有错误,因为视图识别视图模型数组。但是ojtimeline不显示数据,只有一个工作的空视图组件。

看法

<div id="tline"
     data-bind='ojComponent: {
        component: "ojTimeline",
        minorAxis: {
            scale: "hours",
            zoomOrder: ["hours", "days", "weeks"]
        },
        majorAxis: {
        scale: "weeks"
        },
        start: new Date("Jan 1, 2016").toISOString(),
        end: new Date("Jun 31, 2016").toISOString(),
    referenceObjects: [{value: new Date("Feb 1, 2010").toISOString()}],
    series: [{ 
        id: "id",
        emptyText: "No Data.",
        items: statusArray,
        label: "Oracle Events"
    }],
  overview: {
    rendered: "off"
  }                                         
}' style="width: '100%';height: 350px"></div>

视图模型

define(['ojs/ojcore', 'knockout', 'jquery', 'ojs/ojknockout', 'ojs/ojtimeline'],
        function (oj, ko) {
            /**
             * The view model for the main content view template
             */
            function timelineContentViewModel() {
                var self = this;
                this.statusArray = ko.observableArray([]);

                self.addData = function () {
                    $.ajax({
                        url: "http://localhost:8080/myproject/rest/status/v1/findAll",
                        type: 'GET',
                        dataType: 'json',
                        success: function (data, textStatus, jqXHR) {
                            var x = data;
                            for (i = 0; i < x.length; i++) {
                                statusArray.push({
                                    id: data[i].id,
                                    description: data[i].text,
                                    title: data[i].user.screenName,
                                    start: data[i].createdAt});
                            }
                            //$("#tline").ojTimeline("refresh"); Doesn't have ant affect
                        }
                    });
                };
                self.addData();

            }
            return timelineContentViewModel;
        });
4

2 回答 2

0

我已经ojTimeline从 Ajax 数据加载并且从来不需要使用刷新。最坏的情况是,您可以将其包装ojTimeline在 a<!-- ko if ... -->中,这样在您收到 Ajax 响应之前,时间线不会出现。

对于ojTimeline items属性,我不得不像这样解开可观察对象,而不是引用可观察对象items: ko.toJS(statusArray)

要考虑的另一件事是推入循环ko.observableArray内部。for使用该方法的每次推送都会ko.observableArray push()调用订阅。如果您的数组绑定到 UI,那么每次推送都会触发 DOM 更改。相反,通常最好推入底层数组(解包数组)然后调用self.statusArray.valueHasMutated. 您可能还需要注意您对this,self和什么都没有的使用。一致性将有助于避免像发现的一个 ladar 这样的错误。

你如何看待像这样重写你的 for 循环(代码未经测试)?

ko.utils.arrayPushAll(
  self.statusArray(),
  ko.utils.arrayMap(data, function(item) {
    return {
      id: item.id,
      description: item.text,
      title: item.user.screenName,
      start: item.createdAt;
    };
  });
);

self.statusArray.valueHasMutated();

或者,如果您可以侥幸成功(某些 OJ 组件不喜欢这种方法),您可以跳过推送,只需替换可观察对象内的整个数组:

self.statusArray(
  ko.utils.arrayMap(data, function(item) {
    return {
      id: item.id,
      description: item.text,
      title: item.user.screenName,
      start: item.createdAt;
    };
  });
);
于 2016-06-25T04:31:01.837 回答
0

ReferenceError 是由

var statusArray = ko.observableArray([]);

它应该是

this.statusArray = ko.observableArray([])

您还(可能)需要在可观察数组发生更改时刷新时间线,例如在成功回调中的 for 循环之后:

...
success: function (data, textStatus, jqXHR) {
                        var x = data;
                        for (i = 0; i < x.length; i++) {
                            self.statusArray.push({
                                id: data[i].id,
                                description: data[i].text,
                                title: data[i].user.screenName,
                                start: data[i].createdAt});
                        }
                    $("#tline").ojTimeline("refresh");
                    }
...
于 2016-05-26T13:59:29.317 回答