Как Мифрил и 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>