2013-02-11 3 views
4

После многочисленных попыток очистить мои мысли по этому вопросу я подумал, что было бы лучше, если бы я обратился к некоторым специалистам, которые могли бы указать мне в правильном направлении.Как связать модель холста HTML5 с картой данных MVVM/MVP

Концепция заключается в следующем, а скорее основную идею в концепции:

  1. Последние данные извлекаются из базы данных на стороне сервера через регулярные промежутки времени.
  2. Эти данные помещаются в модель, управляемую чем-то вроде Backbone.js, Ember.js или KnockoutJS.
  3. При обновлении элементы на холсте обновляются соответствующей информацией (холст управляется чем-то вроде KineticJS или Fabric.js).
  4. Потенциал для отмены этого процесса, отправка данных обратно на сервер из изменений на холсте.

Так что мой вопрос заключается в следующем: это практично, чтобы связать модель холста (что библиотеки холста) с этим одной из моделей/MVP MVVM? Те, на которые я смотрел, похоже, сосредоточены на HTML-элементах (и я уже обсуждал KnockoutJS ранее в этом контексте), но на этот раз я пытаюсь управлять элементами холста. Если это возможно (или нет), или если требуется решение для дома, что я должен искать, какие подводные камни есть, что я могу пропустить или забыть?

Кажется, something similar came up только пару лет назад, изменилось ли оно с тех пор или это все еще вопрос домашнего выращивания решения? Могут ли ответы на них быть расширены?

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

Заранее спасибо.

ответ

1

Я не уверен, что это отличный ответ, и мне любопытно узнать, есть ли там альтернативы. Но недавно я сделал что-то очень похожее на то, что было предложено в приведенной ссылке.

Если вы посмотрите на Backbone View, то ничего не останется в стороне от материалов управления DOM, которые, как вы сказали, бесполезны для элементов холста. Итак, я создал простой объект в стиле, подобном представлению Backbone's View, для использования с элементами холста (я использовал easel.js).

Я не могу утверждать, что этот код завершения или что-нибудь, так как я просто играл с easelJS немного ...

var CanvasView = function(options) { 
     this.model = options.model; 
     this.initialize.apply(this, arguments); 
    }; 
_.extend(CanvasView.prototype, Backbone.Events, { 
    initialize: function(options) { 
     // in extended view, hook up to model change events, etc. 
     // Since I used easel, here I also created some easel DisplayObjects, 
     // then update their positions/etc. in response to model changes. 
    } 
}); 

Я думаю, что если я когда-либо работать над этим еще, было бы больше добавленный материал, как встроенный «контейнер», и, возможно, декларативный хэш, похожий на Backbone View.

1

Я действительно думаю, что вы могли бы сделать это, с небольшой работой.

Я подключил элементы Raphael.js к модели представления, используя custom bindings, и вы могли связываться с вашим кликом по событию (при условии, что он есть) для вашей модели просмотра, используя инфраструктуру pub/sub. Я бы порекомендовал плагин jQuery pubsub.

У меня есть jsFiddle example, который вы можете найти для справки, хотя учтите, что я создал это, чтобы продемонстрировать проблему, с которой я столкнулся, чтобы уничтожить повторное создание элементов холста, если вы перемещаетесь в сторону от вида и вернитесь, так что это не идеально. Но вы должны быть в состоянии понять суть этого.

важные разделы, чтобы смотреть на это обычай связывание в HTML код:

<div class="span10" data-bind="foreach: Current"> 
    <div class="gauge" data-bind="createGauge: $data"></div> 
</div> 

Обычай связывания JS код:

// Knockout handler to create a gauge for each bound item 
ko.bindingHandlers.createGauge = { 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     ko.utils.unwrapObservable(viewModel.updated); 
     var gaugeName = viewModel.Name; 
     var substation = bindingContext.$parent; 

     var gaugeObject = substation.Gauges[gaugeName]; 

     // I cannot, for the life of me, get the gauge to redraw properly if I just 
     // redraw the inner. Leave the real-time values page and come back, and 
     // all the gauges are no longer visible. 
     // So destroy the existing one and recreate it from scratch. 
     // Yes, this is annoying! 
     if (gaugeObject) { 
      gaugeObject.gauge.removeChildren(); 
      gaugeObject.gauge.clear(); 
      gaugeObject.gauge.remove(); 
      gaugeObject.gauge = null; 
      gaugeObject.paper.clear(); 
      gaugeObject.paper.remove(); 
      gaugeObject.paper = null; 
      gaugeObject = null; 
     } 

     if (!gaugeObject) { 
      var gaugeSize = $(element).height(); 
      var paper = new Raphael(element, gaugeSize, gaugeSize); 
      var gauge = paper.gauge(viewModel); 
      gaugeObject = { 
       'paper': paper, 
        'gauge': gauge 
      }; 
      substation.Gauges[gaugeName] = gaugeObject; 
     } 

     gaugeObject.gauge.updateValue(viewModel); 
    } 
}; 

Код калибра Рафаэль (я не буду копировать его здесь, это долго, но обратите внимание, что у меня есть только одна наблюдаемая ссылка в этом коде, в противном случае калибровка будет обновляться для каждого обновленного свойства, и я хотел бы обновить все свойства модели представления за один раз, но только один раз), где я привязываю элемент холста нажмите функцию в рамках PubSub:

gauge.clickFunction = function() 
{ 
    $.publish('/history', [point.IOReference]); 
}; 

В моем коде, что только переходит на другую точку зрения, но на соответствующем подписываться обработчике код обновить модель представления и сохранить его обратно на сервер, если вы хотите ,

+0

Правильно, это честная битка. Позвольте мне обойти его, в этом случае вы наблюдаете за событием навигации, чтобы обновить калибры, правильно? Используя ту же концепцию привязки с помощью KOJS, могу ли я привязать к изменениям в другой модели, которая обновляется через запрос AJAX? Или изменения в модели нокаута, но тогда мне придется перерисовать весь холст, не так ли? Как я привязываюсь к этому, а не к отдельным предметам холста? – Skyrail

+0

Ну, я использую навигацию, чтобы перейти на другую страницу в приложении одиночной страницы, но принцип тот же. Будет вашей моделью просмотра, которая будет иметь обработчик $ .subscribe, который будет уведомлен о возникновении события клика, а затем вы можете обновить все, что захотите, в этой модели. У меня есть гораздо более сложный холст, который я подключил к KO, и у меня есть функция набора в этом холсте, который принимает модель представления, и перерисовывает части холста, которые нуждаются в обновлении. Если вы можете получить доступ к другой модели представления в функции обновления, вы можете привязываться к ней и иметь ее доступную. –

+0

У меня есть этот холст, настроенный так, чтобы он обновлялся в результате вызова AJAX. Это делает его более ясным? Я полагаю, что это, вероятно, не будет! Я бы опубликовал еще несколько кода, но этот холст составляет около 2000 строк js! –

Смежные вопросы