18

I am using Mithril as our MVC framework & I want to leverage of rich JQuery/Jquery UI functionalities. I would like to understand the 'Do's and Don't's' when combining jQuery with Mithril

What I understand is, I can use Mithril config to access the real DOM element & bind to various jQuery functions safely.

Using jQuery UI functions with Mithril

But what about using jQuery selectors on classes or ids to locate the real DOM element, like

attaching a jQuery date picker

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

or hiding a div

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

What is the danger of inprogress m.render causing $('blah') === undefined.

Would really like to understand the how these 2 components could/should interact with each other.

4

2 回答 2

20

简而言之,所有config函数都保证在 DOM 树创建后运行。因此,在配置中,您可以调用 $(bla) 而不必担心元素是否已绘制。

Mithril 的警告(或者任何允许安装和卸载子模板的系统)是可以通过条件逻辑从 DOM 中删除元素。因此,建议您附加config到将受 jQuery 插件影响的元素,或者将元素的子树包装在函数中,以使使用 querySelector 的配置更明显适用于该特定元素范围。

对于大量的 jQuery 调用,被查询的元素是否存在实际上并不重要(例如,如果页面中不存在 ',$(".foo").hide()则根本不执行任何操作)。.foo

需要关注的主要事情是您不想从 DOM 本身驱动太多状态(这在 jQuery 中有点惯用)。例如,切换面板的可见性可能在 jQuery 中可以更快地完成,但如果规范数据源是 DOM 中的 CSS 类,则更难从页面加载中同时达到可见和不可见状态它由 jQuery 代码控制,而不是单向流入视图的视图模型标志。

于 2014-11-26T15:44:08.937 回答
19

让我们首先弄清楚每个库在做什么:Mithril 是一个 MVC 脚手架,用于定义应用程序的结构和生命周期。Mithril 的视图定义了 DOM,包括 DOM 元素将拥有的 ID,并且还会指示这些元素何时被删除或更改;jQuery UI 用于定义位于广泛视图结构中的小部件的行为。

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="https://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css" 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>

以 jQuery 的方式考虑这个问题的最佳方式可能config是有点像 DOM 就绪:

$( document ).ready( function thisIsABitLikeAConfigFunction( element ){
  // Except that DOM ready only works on the document element
}  );
于 2014-11-26T14:27:26.583 回答