Перенаправить вывод JS с HTML на переменные C#

206
07 августа 2018, 21:20

Использую CefSharp.WPF

Задача состоит в получении текущего значения динамически изменяемого графика. Отыскав ответственный за обновление данных скрипт, нашёл вот такой пример:

define('components/Chart', ['lib/react'], function (React) {
    return React.createClass({
        displayName: 'Chart',
        ...
        _draw: function () {
            var canvas = this.refs.canvas.getDOMNode();
            var ctx = canvas.getContext('2d');
            this.graph.setData(...);
            this.graph.calculatePlotValues();
            this.graph.clean();
            this.graph.drawAxes();
            this.graph.drawGraph();
            this.graph.drawIndexes();
            this.graph.drawData(...);
        }
        ...
        render: function () {
            ...
        }
    });
}

*this.graph - имеет тип Graph и определён аналогичным образом (через define и React.createClass).

Сайт рисует график на canvas с о чём то говорящим атрибутом data-reactid.

Я в JS не разбираюсь, но задача была поставлена так, что об этом сожалею :) Однако, прошу помочь мне разобраться что, собственно, этот скрипт делает. Думаю представленного общего вида хватит, чтобы это понять.

Разобравшись с этим, я планирую как то переопределить, если это возможно, Chart, чтобы тот не рисовал данные на canvas, а писал их в глобальную переменную, откуда я мог бы методом EvaluateScriptAsync это читать.

Было предложение создать аналогичный класс в C#, затем зарегистрировать его в JS методом RegisterJsObject. Таким образом, мы получим контроль над данными внутри класса, что нам и нужно. Однако, остаётся вопросом как правильно это сделать и будет ли это работать...

Answer 1

React это библиотека для отрисовки пользовательских компонентов, нынче очень популярна за счет своей архитектуры и философии. Тут можно посмотреть что да как.

Если вкратце, то в React любой элемент интерфейса - это компонент, у которого есть состояние state и который может принимать св-ва props, за счет них компонент возвращает вполне реальный DOM.

Каждый компонент описывается классом, которые наследуется от базового React.Component. Метод render как раз таки возвращает DOM ( на самом деле все чуть сложнее, но к делу не относится )

Простой пример:

class SimpleComponent extends React.Component {
    render() {
        return (
            <div>Hello, world</div>
        );
    }
}

data-reactid это просто атрибут показывающий корневой элемент, где находится все приложение.

В зависимости от версии, которую вы используете ( судя по createClass оч старая ) можно попробовать вытащить данные из DOM. Но надо знать точную версию, без нее помочь вам с этим не смогу.

Ели все таки хотите менять код, то переопределите метод createClass: добавляйте все инстансы в какой-нибудь массив/объект, что бы потом по ссылке получать актуальный компонент

Вот конструктор, который возвращает createClass, можно в нем поменять кое-что ( брал код от сюда )

createClass: function(spec) {
  var Constructor = function(props, context) {
    // код библиотеки
    // добавляем экземпляр в глобальный массив
    if(!window.globalComponents) {
      window.globalComponents = [];
    }
    window.globalComponents.push(this);
  }
  // остальной код
};

Потом можно легко по displayName найти наш компонент

window.globalComponents.find(c => c.displayName === 'Chart');
READ ALSO
Проверка на наличие в DataGridView

Проверка на наличие в DataGridView

Требуется пройти по DataGridView и найти там определенные данные, введенные с textboxКак это реализовать?

155
Как отслеживать изменения в DB MS SQL 2008 на C# через Service Broker?

Как отслеживать изменения в DB MS SQL 2008 на C# через Service Broker?

Никак не могу разобраться с вопросом отслеживания изменений в базе данных

173
WPF Как реализовать асинхронность

WPF Как реализовать асинхронность

Имеется команда, которая по выделенной книге находит студентов, которым выдана книга

172