当前位置: 首页 > 工具软件 > MooTools > 使用案例 >

mootools_介绍MooTools模板化

曹经业
2023-12-01

mootools

One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating:

使用MooTools JavaScript框架创建UI组件的一个主要问题是,没有一种允许自定义模板和简化节点创建的好方法。 到目前为止,有两种创建方法:

新元素疯狂 (new Element Madness)

The first way to create UI-driven widgets with MooTools is creating numerous elements programmatically. The following snippet is taken from my MooTools LightFace plugin:

使用MooTools创建UI驱动的小部件的第一种方法是以编程方式创建大量元素。 以下代码摘自我的MooTools LightFace插件:


//draw rows and cells;  use native JS to avoid IE7 and I6 offsetWidth and offsetHeight issues
var verts = ['top','center','bottom'], hors = ['Left','Center','Right'], len = verts.length;
for(var x = 0; x < len; x++) {
	var row = this.box.insertRow(x);
	for(var y = 0; y < len; y++) {
		var cssClass = verts[x] + hors[y], cell = row.insertCell(y);
		cell.className = cssClass;
		if (cssClass == 'centerCenter') {
			this.contentBox = new Element('div',{
				'class': 'lightfaceContent',
				styles: {
					width: this.options.width
				}
			});
			cell.appendChild(this.contentBox);
		}
		else {
			document.id(cell).setStyle('opacity',0.4);
		}
	}
}

//draw title
this.title = new Element('h2',{
	'class': 'lightfaceTitle',
	html: this.options.title
}).inject(this.contentBox);

//draw message box
this.messageBox = new Element('div',{
	'class': 'lightfaceMessageBox',
	html: this.options.content || '',
	styles: {
		height: this.options.height
	}
}).inject(this.contentBox);

//button container
this.footer = new Element('div',{
	'class': 'lightfaceFooter',
	styles: {
		display: 'none'
	}
}).inject(this.contentBox);

//draw overlay
this.overlay = new Element('div',{
	html: ' ',
	styles: {
		opacity: 0
	},
	'class': 'lightfaceOverlay',
	tween: {
		link: 'chain',
		duration: this.options.fadeDuration,
		onComplete: function() {
			if(this.overlay.getStyle('opacity') == 0) this.box.focus();
		}.bind(this)
	}
}).inject(this.contentBox);

The problem with creating elements programmatically within widgets is that doing so means your class becomes inflexible. What if you want one of the elements to have a specific CSS class? What if you want one of the elements to be a DIV instead of a SPAN? What if you don't want one or more of the elements generated by the class? You would need to extend the class and override the method that created all of the elements. Yuck.

在窗口小部件中以编程方式创建元素的问题是这样做意味着您的班级变得僵硬。 如果您希望其中一个元素具有特定CSS类怎么办? 如果您希望其中一个元素是DIV而不是SPAN,该怎么办? 如果您不希望类生成一个或多个元素怎么办? 您将需要扩展类并覆盖创建所有元素的方法。 uck

用户信赖 (User Reliance)

The second way to create UI-driven classes is to rely on the developers using your classes to provide the correct elements to the class in the correct hierarchy. This could include providing elements to the initialize method of a class' instance. I dislike this method for complex widgets because there's too much reliance on the user to figure out what elements your class needs.

创建UI驱动的类的第二种方法是依靠使用您的类的开发人员为正确的层次结构中的类提供正确的元素。 这可能包括为类实例的initialize方法提供元素。 我不喜欢这种用于复杂小部件的方法,因为用户过多地依赖它来确定类需要哪些元素。

解决方案:MooTools模板化 (The Solution: MooTools Templated)

Templated is a MooTools mixin class which creates elements for classes using a string-based HTML template which may included embedded attach points and events. Templated is very much inspired by the Dojo Toolkit's dijit._Template resource, which has been tried, tested, and proven in Dojo's outstanding Dijit UI framework. Let's explore what Templated is and how to use it!

模板化是MooTools的mixin类,它使用基于字符串HTML模板为类创建类的元素,该模板可能包含嵌入式附加点和事件。 模板化非常受Dojo Toolkit的dijit._Template资源的启发,该资源已在Dojo出色的Dijit UI框架中进行了尝试,测试和验证。 让我们探索什么是模板化以及如何使用它!

模板和条款 (Templates and Terms)

Before using the Templated mixin, it's important to understand a few concepts and terms. Take the following template for example:

在使用模板化混合器之前,了解一些概念和术语很重要。 以以下模板为例:


<div class='UIWidget'>
	<p>{message}</p>
	<input type='text' data-widget-attach-point='inputNode' data-widget-attach-event='keyup:onKeyUp,focus:onFocus' />
	<div type='submit' data-widget-type='UIWidgetButton' data-widget-attach-point='buttonWidget,submitWidget' data-widget-attach-event='click:onSubmit' data-widget-props='label:\"My Prop Label\",somethingElse:true'></div>
</div>

Within the template you'll see attach points, attach events, and props. Attach points are named properties which will be attached to the widget instance and map to the given node within the template. Attach events are key (event type) => value (event handler) mappings separated by a colon. Multiple attach points can refer to the same element, and an elements may have many attach events; both a comma-separated. Props are configuration properties for the node's given instance if the node is mean to be a widget itself. Props are written in JSON-style syntax and property keys should match the element options; the options and props (if they exist) are merged.

在模板中,您将看到附加点,附加事件和道具。 附加点是命名属性,将附加到小部件实例并映射到模板中的给定节点。 附加事件是键(事件类型)=>值(事件处理程序)映射,用冒号分隔。 多个附接点可以引用同一元素,并且一个元素可能具有许多附接事件。 两者都用逗号分隔。 如果节点是控件本身,则属性是节点给定实例的配置属性。 道具以JSON样式的语法编写,并且属性键应与element选项匹配; 选项和道具(如果存在)将合并。

The following snippet should provide a bit more clarity as to what each mean:

以下代码段应更清楚地说明每个含义:


// Representation of an instance created with Templated
{
	buttonWidget: "<input type='submit' />",
	inputNode: "<input type='text' />",
	onKeyUp: function() { }, // fires upon keyup on the text field
	onFocus: function() { }, // fires upon focus event on the text field
	onSubmit: function() { }, // fires upon submit button click
	submitWidget: "<input type='submit' />"
	
	// More classes here
	
}

Attach points, events, and props are all very simply to use but provide an essential function for maximum customization in UI widget templating. Templated also looks for string substitution (String.substitute) opportunities, allowing you to add basic variables within your templates.

附加点,事件和道具都非常易于使用,但提供了用于在UI小部件模板中实现最大程度自定义的基本功能。 模板化还会寻找字符串替换( String.substitute )的机会,从而使您可以在模板中添加基本变量。

使用MooTools模板化 (Using MooTools Templated)

To use Templated within MooTools, add Templated to your class' Implements array:

要在MooTools中使用模板化,请将模板化添加到您的类的Implements数组中:


Implements: [Options, Templated]

With Templated available within the class, a few more options are available within the class:

通过在班级中使用模板化,班级中可以使用更多选项:

  • template: The string HTML template for the class, including attach points, events, props, and subwidgets.

    template:该类的字符串HTML模板,包括附加点,事件,道具和子部件。

  • templateUrl: The URL to the widget's template if it's external. A basic Request will be sent to retrieve the widget if not yet cached.

    templateUrl:小部件模板的URL(如果位于外部)。 如果尚未缓存,将发送一个基本请求以检索小部件。

  • element: The element which the widget's domNode will replace.

    element:小部件的domNode将替换的元素。

  • widgetsInTemplate: If true, parses the widget template to find and create subwidgets. Inline attach points and attach events are added to the parent widget, not the subwidget.

    widgetsInTemplate:如果为true,则解析窗口小部件模板以查找和创建子小组件。 内联附加点和附加事件将添加到父窗口小部件, 而不是子窗口小部件。

  • propertyMappings: An object which contains custom property mappings for the widget.

    propertyMappings:一个对象,其中包含窗口小部件的定制属性映射。

  • defaultPropertyMappings: An object with default, fallback property mappings for the widget. Property mappings included ID, style, and class, which these properties are carried over from the base element to the domNode.

    defaultPropertyMappings:一个对象,具有窗口小部件的默认后备属性映射。 属性映射包括ID,样式和类,这些属性从基本元素转移到domNode。

When you desire for the template to be parsed and nodes to be created, calling this.parse() will accomplish that task. You will usually want to call this method within the initialize method after the options have been set:

当您希望解析模板并创建节点时,调用this.parse()将完成该任务。 设置选项后,通常需要在initialize方法中调用此方法:


// The magical constructor
initialize: function(options) {

	// Set the options
	this.setOptions(options);

	// Parse the template
	this.parse();
},

With the attach points and events in place, you can code your UI class per usual, using the attach points to refer to nodes when needed. Here's a sample UI widget with subwidgets:

有了附加点和事件,您就可以照常编写UI类,并在需要时使用附加点引用节点。 这是带有子小部件的示例UI小部件:


var UIWidget = new Class({

	// Implement the new Templated class
	Implements: [Options, Templated],

	// The UI template with attachpoints and attachevents
	options: {
		template: "
   
   
" + "

{message}

" + " " + "
" + "
", uiwidgetOption: "here!" }, // The magical constructor initialize: function(options) { this.debug("[widget] Initialize"); // Set the options this.setOptions(options); // Parse the template this.parse(); }, onKeyUp: function(evt) { }, onFocus: function() { this.inputNode.set("value", ""); }, onSubmit: function(evt) { evt.stop(); }, onMouseEnter: function() { this.domNode.setStyle("background","pink"); }, onMouseLeave: function() { this.domNode.setStyle("background","lightblue"); } }); // Create a button widget var UIWidgetButton = new Class({ // Implement the new Templated class Implements: [Options, Templated], // The UI template with attachpoints and attachevents options: { template: "", uiwidgetOption: "here too!", label: "Default Submit Option" }, // The magical constructor initialize: function(options) { // Set the options this.setOptions(options); // Parse the template this.parse(); }, // onClick onClick: function(evt) { evt.stop(); } });

Your UI widget has been created with flexibility and ease of use in mind!

创建UI小部件时要考虑到灵活性和易用性!

模板化事件 (Templated Events)

Templated provides stub methods along the way so code can be executed at different points within the creation of the widget:

模板化提供了存根方法,因此可以在创建小部件的不同点执行代码:

  • postMixInProperties: Fires after the options and widget properties have been mixed.

    postMixInProperties:在选项和窗口小部件属性混合后触发。

  • postCreate: Fires after the widget nodes have been created but before the nodes are placed into the DOM

    postCreate:在创建小部件节点之后但将节点放置到DOM中之前触发

  • startup: Fires after the widget has been created and is placed into the DOM

    启动:在创建小部件并将其放入DOM后触发

These methods have proven to be useful within the Dojo Toolkit.
这些方法在Dojo Toolkit中被证明是有用的。

模板化助手 (Templated Helpers)

Templated also provides two essential widget helpers: Element.parse and document.widget. Element.parse allows for declarative (node-based) widget creation. So if your page contains nodes with data-widget-type properties, you can use the parse method of elements to find widgets and subwidgets. Take the following HTML:

模板化还提供了两个基本的小部件助手:Element.parse和document.widget。 Element.parse允许声明式(基于节点)小部件创建。 因此,如果页面包含具有data-widget-type属性的节点,则可以使用元素的parse方法查找小部件和子小部件。 使用以下HTML:


<!-- Declarative --> 
<div id="qHolder2" data-widget-type="UIWidget" data-widget-props="message:'This is the second widget!'" class="UIWidgetInstance2"></div>

Running the following JavaScript snippet would parse the page, find the DIV, and create a widget from it!

运行以下JavaScript代码片段将解析该页面,找到DIV并从中创建一个小部件!


document.body.parse();

The document.widget method accepts a DOM node and returns the widget object which it represents:

document.widget方法接受一个DOM节点并返回其表示的小部件对象:


var myWidget = document.widget("qHolder2");

Being able to retrieve a widget based on a node is very helpful in debugging your application.

能够基于节点检索小部件对于调试应用程序非常有帮助。

现实用法 (Realistic Usage)

One of the popular UI plugins I've created is LightFace, the Facebook-like lightbox. Unfortunately LightFace falls victim to the "new Element Madness" because of the complexity of the widget structure. Many people were unhappy about its table-based structure (which accommodated for IE6) and wanted a DIV-based structure...and with Templated, you can make that happen.

我创建的最受欢迎的UI插件之一是LightFace,类似于Facebook的灯箱。 不幸的是,由于小部件结构的复杂性,LightFace成为“新元素疯狂”的受害者。 许多人对其基于表的结构(适用于IE6)感到不满,并希望基于DIV的结构...通过Templated,您可以实现这一目标。

Here's what LightFace would look like with Templated:

这是使用Templated的LightFace的外观:


<table class="lightface" data-widget-attach-point="box">
	<tbody>
		<tr>
			<td class="topLeft"></td>
			<td class="topCenter"></td>
			<td class="topRight"></td>
		</tr>
		<tr>
			<td class="centerLeft"></td>
			<td class="centerCenter">
				<div class="lightfaceContent" data-widget-attach-point="contentBox">
					<h2 class="lightfaceTitle lightfaceDraggable" data-widget-attach-point="title">{title}</h2>
					<div class="lightfaceMessageBox" data-widget-attach-point="messageBox">{message}</div>
					<div class="lightfaceFooter" data-widget-attach-point="footer"></div>
					<div class="lightfaceOverlay" data-widget-attach-point="overlay"></div>
				</div>
			</td>
			<td class="centerRight"></td>
		</tr>
		<tr>
			<td class="bottomLeft"></td>
			<td class="bottomCenter"></td>
			<td class="bottomRight"></td>
		</tr>
	</tbody>
</table>

And if you restructured the LightFace CSS file to accommodate for DIV-based structure, the template could look like:

并且,如果您重组了LightFace CSS文件以适应基于DIV的结构,则该模板可能如下所示:


<div class="lightface" data-widget-attach-point="box">
	<div class="lightfaceContent" data-widget-attach-point="contentBox">
		<h2 class="lightfaceTitle lightfaceDraggable" data-widget-attach-point="title">{title}</h2>
		<div class="lightfaceMessageBox" data-widget-attach-point="messageBox">{message}</div>
		<div class="lightfaceFooter" data-widget-attach-point="footer"></div>
		<div class="lightfaceOverlay" data-widget-attach-point="overlay"></div>
	</div>
</div>

The presentation state of widget would be completely in the developer's hands with Templated!

有了Templated,小部件的呈现状态将完全在开发人员手中!

测试版! (BETA!)

Templated is currently in BETA state, so please report any bugs you find along the way. A stable UI solution for MooTools will do everyone a favor.

模板化目前处于BETA状态,因此请报告在此过程中发现的所有错误。 稳定的MooTools UI解决方案将为每个人带来帮助。

获取模板! (Get Templated!)

The ability to apply this level of control to widget templating is amazing. Dijit's use of _Templated help makes the UI framework the best available for any JavaScript framework. Please consider using Templated for your UI work, especially if your components are open source or maintained by a team. Have fun with your UIs!

将此控制级别应用到小部件模板的功能是惊人的。 Dijit对_Templated帮助的使用使UI框架最适合任何JavaScript框架。 请考虑在您的UI工作中使用模板化,尤其是当您的组件是开源的或由团队维护时。 尽情享受您的UI!

翻译自: https://davidwalsh.name/templated

mootools

 类似资料: