Привязать компонент ojtimeline OracleJet к viewModel

Я пытаюсь понять, как я могу привязать данные из модели представления к представлению. 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>

View-модель

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;
        });

2 ответа

Ошибка 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");
                    }
...

Я загрузил ojTimeline из данных Ajax и никогда не нужно было использовать обновление. В худшем случае, вы можете обернуть ojTimeline в <!-- ko if ... --> так что временная шкала не появится, пока вы не получите ответ Ajax.

Для ojTimelineitems Атрибут, вместо того, чтобы ссылаться на наблюдаемое, мне пришлось развернуть наблюдаемое следующим образом: items: ko.toJS(statusArray),

Еще одна вещь, которую следует учитывать, это подталкивать ko.observableArray внутри for петля. Каждый толчок с использованием ko.observableArraypush() Метод вызывает подписки. Если ваш массив связан с пользовательским интерфейсом, то каждое нажатие будет вызывать изменение DOM. Вместо этого часто лучше нажать на базовый массив (развернуть массив), а затем вызвать self.statusArray.valueHasMutated, Вы также можете следить за использованием this, self, и ничего. Последовательность поможет избежать ошибок, таких как идентифицированный один ладар.

Что вы думаете о переписывании вашего цикла 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 не нравится этот подход), вы можете пропустить push и просто заменить весь массив внутри наблюдаемой:

self.statusArray(
  ko.utils.arrayMap(data, function(item) {
    return {
      id: item.id,
      description: item.text,
      title: item.user.screenName,
      start: item.createdAt;
    };
  });
);
Другие вопросы по тегам