Как Мифрил и jQuery взаимодействуют друг с другом?

Я использую Mithril как свою структуру MVC, и я хочу использовать богатые функциональные возможности JQuery/JQuery UI. Я хотел бы понять "Do and Do not" при объединении jQuery с Mithril

Насколько я понимаю, я могу использовать конфигурацию Mithril для доступа к реальному элементу DOM и безопасному привязке к различным функциям jQuery.

Использование функций пользовательского интерфейса jQuery с помощью Mithril

Но как насчет использования селекторов jQuery для классов или идентификаторов для определения реального элемента DOM, например

установка jQuery date picker

  beforeShow: function(input, inst) {
   $('#ui-datepicker-div').addClass("mydatepicker");
  },

или сокрытие div

 $("#mydiv").hide();

Какова опасность inprogress m.render, вызывающая $('blah') === undefined.

Хотелось бы понять, как эти 2 компонента могут/должны взаимодействовать друг с другом.

Ответы

Ответ 1

Вкратце, все функции config гарантированы для запуска после создания дерева DOM. поэтому изнутри config вы можете вызвать $(bla), не беспокоясь о том, был ли элемент нарисован.

Предостережение с Мифрилом (или, если на то пошло, любая система, позволяющая монтировать и размонтировать подтемы) состоит в том, что элементы могут быть удалены из DOM условной логикой. Из-за этого он рекомендовал либо прикрепить config к элементу, на который будет влиять плагин jQuery, либо обернуть поддерево элементов в функции, чтобы сделать его более очевидным, что применяется конфигурация, использующая запросSelector к этому конкретному диапазону элементов.

Для большого количества вызовов jQuery на самом деле не имеет значения, есть ли этот запрос или нет (например, $(".foo").hide() просто ничего не делает, если на странице не присутствует .foo).

Главное, чтобы вас беспокоило то, что вы не хотите управлять слишком большим состоянием из самой DOM (что несколько идиоматично в jQuery). Например, переключение видимости панели может быть чем-то, что можно сделать быстрее в jQuery, но сложнее достичь как видимых, так и невидимых состояний, скажем, загрузки страницы, если канонический источник данных является классом CSS в DOM который управляется кодом jQuery, вместо флага представления, который однонаправленно втекает в представление.

Ответ 2

Сначала определим, что делает каждая библиотека: Mithril - это каркас MVC, который используется для определения структуры и жизненного цикла вашего приложения. Мифриловые представления определяют DOM, включая те идентификаторы, которые будут иметь элементы DOM, а также будут диктовать, когда эти элементы будут удалены или изменены; Пользовательский интерфейс jQuery используется для определения поведения виджетов, которые находятся в вашей более широкой структуре представлений.

Mithril предоставляет атрибут config для раскрытия функции, которая дает вам доступ к "реальному элементу DOM", о котором вы говорите. Функция выполняется всякий раз, когда представление Mithril визуализировалось или изменилось: первым аргументом является элемент DOM; второй аргумент false, если элемент только что был создан, и true в противном случае; третьим аргументом является context - он позволяет вам определить дополнительное поведение, прежде чем элемент будет удален из DOM.

config будет выполняться только тогда, когда элемент действительно существует, и предоставляет ссылку для него. По этой причине ваш код jQuery UI должен находиться внутри этой функции. Преимущество этого в том, что вам никогда не нужна ссылка на стиль селектора CSS для элемента, потому что config всегда предоставляет прямую ссылку в качестве первого аргумента. Перепишите свой первый фрагмент таким образом:

m.module( document.body, {
  controller : function(){
  },
  // Because the view is generated by Mithril code 
  // (which could change the classes or IDs, or remove elements entirely...
  view       : function(){
    return m( '.this', 
             m( '.is', 
               m( '.all', 
                 m( '.rendered', 
                   m( '.by', 
                     m( '.mithril', 
                       // ...None of this is referenced by jQuery. 
                       m( 'input[placeholder=Rendering by Mithril!]', {
                         // All jQuery happens in external functions, attached like this:
                         config : configDatePicker
                       } ) ) ) ) ) ) );
  }
} )

// ...Meanwhile...

function configDatePicker( element, init, context ){
  // We don't want to add the class all the time, only the first time the element is created
  if( !init ){
    // Here we reference the element directly, and pass it to jQuery
    $( element ).datepicker().on( 'click', function(){
      $( element ).val( 'Behaviour by jQuery!' )
    } );
    
    // We can also bind an event to trigger behaviour when the element is destroyed
    context.onunload = function(){
      // …But this will never happen because our code doesn't do that ;)
      alert( '.mydatepicker is going to be destroyed!' )
    };
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="#" onclick="location.href='https://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css'; return false;" rel="stylesheet"/>
<script src="http://cdnjs.cloudflare.com/ajax/libs/mithril/0.1.24/mithril.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.2/jquery-ui.min.js"></script>