”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 绑定和模板:Peasy-UI 系列的一部分

绑定和模板:Peasy-UI 系列的一部分

发布于2024-11-08
浏览:931

Bindings and Templates: Part f the Peasy-UI series

Table of Contents

  1. Introduction
  2. Bindings and the Template
  3. Text Bindings
    • Basic Binding
    • Conditional Boolean Text Binding
    • One-time Text bindings
  4. Attribute Bindings
    • Bindings for element attributes
    • Bindings for events
    • Binding whole elements to data model
    • Binding for Rendering
    • Binding for Arrays
    • Bindings for Components
  5. Getters
  6. More information
  7. Conclusion

Introduction

Today we are going to dive a layer deeper into the Peasy-UI library. We are going to explain the different types of bindings that are available in the library, and how you can incorporate them into the string literal template that you provide to the library to be rendered to the DOM. For this article all examples are provided using TypeScript, but the library works with vanilla JavaScript perfectly fine.

If you missed the introduction article for Peasy-UI, you can read it
here, and it can provide the overview for the library, and even introduces upcoming topics in the series.

Bindings and the Template

I quick recap of what bindings are, what the template is, and how they work with the library to give you control of what gets rendered to the DOM.

Peasy-UI is a library that injects content into DOM elements that you specify. The content that gets injected is dictated by a string literal template that provides HTML markup that represents the content to be injected.

const template = `
  
Render Me
`;

This is an example of the string literal template that you pass to Peasy-UI and it will render it into the targeted DOM element.

Bindings provide a means to control that template dynamically. For example, let's do a Hello World example.

const model = {
  name: "Bob",
};

const template = `
Hello: \${name}!!!!
`; await UI.create(document.body, model, template).attached;

This code creates the data store (model), that is bound to the html in the string literal template. UI.create() takes the model, template, and the targeted DOM element to inject into as parameters. In your JavaScript code, you can change model.name to whatever string you'd like, and it will dynamically re-render the new text into the DOM. Side note: the await in the UI.create() method pauses the execution of subsequent logic until Peasy-UI attaches the content into the DOM. This way you can prevent trying to make changes or access DOM content that isn't rendered yet.

Text bindings

There are two types of bindings in Peasy-UI, text bindings and attribute bindings, and we will explore both types. One thing to note is that since we are providing a string literal to Peasy-UI, we use the backslash escape character to designate it as a binding.

Basic binding

The most basic binding is simply injecting data into the DOM as text. The Hello World above is a prime example of this. Use cases for this binding can include manipulating the inner text or inner HTML content inside a DOM element, such as changing a name. I've also used this for changing CSS properties inside a CSS string.

BINDING: ${propertyName}

As in the example above, we can use this:

const model = {
  name: "Bob",
};

const template = `
Hello: \${name}!!!!
`;

The binding maps the 'name' property to the tag in the HTML and replaces name with the name content from the model.

Conditional boolean text binding

In order to control if a binding is active, we can leverage some conditional bindings.

BINDING: ${'value' = propertyName}

BINDING: ${'value' ! propertyName}

An example of this would be:

const model = {
  darkMode: true,
};

const template = `
I am using \${'Dark mode' = darkMode} \${'Light mode' ! darkMode} now!
`;

Based on the truthy status of the darkMode property in the model, different text renders. If true, the div will say I am using Dark mode now! and if its set to false, it will render I am using Light mode now!.

One-time text bindings

The previous bindings get constantly evaluated with respect to RequestAnimationFrame(). However, sometimes you may only want to evaluate it one-time, like on initialization. Peasy-UI provides one-time bindings.

BINDING: ${|'value' = prop}

BINDING: ${|'value' ! prop}

The same example above can be reused, the only difference is that the evaluation of the darkMode property will only be done on the first rendering cycle. Please take note of the pipe character in the binding, as that is what designates it as a one-time binding.

Attribute Bindings

Attribute bindings use either \${ } or the pui attribute within an element tag to affect the behaviour of the element. For the sake of this article we will continue using the \${ } nomenclature. We will explore the different methods of assigning bindings in a future article.

Bindings for element attributes

Peasy-UI gives us the power to access element attributes and allows us to monitor and control those values easily.

There are four basic element attribute bindings:

BINDING: ${attribute

BINDING: ${attribute

BINDING: ${attribute ==> propertyName} bind in one direction, from the element to the model

BINDING: ${attribute propertyName} bi-directional, or two-way, between the element and the model

Let's look at some examples of this:

const model = {
  color: "red",
};

const template = `
color}>Red color}>Green
`;

In this example you are binding a custom attribute on each element 'red' and 'green' to the color property in the model. When the radio button in this group is selected, it changes the data in the model property 'color'.

Another simple example:

const model = {
  userName: "",
};

const template = `
userName}>
`;

This is a one way binding from the text field, that sets the data model value of userName to whatever is entered into the input field.

Let's look at a bidirectional example:

const model = {
  userName: "Bob",
};

const template = `
userName}>\${userName}
`;

The magic that exists here is that you can set username in the data model programmatically, and it will automatically change the rendered text in the input field. Or, you can type into the input field and it will dynamically change the value in the data model.

Bindings for events

So what if want to render a drop down select input, or a button? Peasy-UI gives you access to mapping the event listeners automatically and tying them into the data model.

BINDING: ${ event @=> callbackName}

Buttons provide easy examples for this, but all DOM events can be used.

const model = {
  clickHandler: (event: HTMLEvent, model: any, element: HTMLElement, eventType: string, object: any) => {
    window.alert("I got clicked");
  },
};

const template = `
`;

Okay, there is a bit to unpack here. First lets focus on the binding, you can bind any HTML DOM event, such as change, input, click, mouseenter, etc... as an event binding, and then you provide the 'handler' callback which exists IN the data model.

Peasy passes 5 standard parameters into the handler for your convenience. The first parameter is the HTMLEvent that actually is fired.The second parameter is the 'localized' data model that is bound to the element. This CAN be tricky, because depending on your nesting of elements, it maybe be a localized data model for just that element, or if it is a top level binding, it will be the standard data model. We will get into nesting a bit later, but just know that another option is provided to help with this.

The third parameter is the target element that fired the event, so you can access any attributes nested in the element. The fourth element is the string representation of the event, such as 'click' or 'change' and this helps in case you bind multiple events to the same callback, you can distinguish which event triggered this callback. The final parameter is the overarching data model. Inside this object, regardless of how nested your binding is, will be an object that contains the model property, and you can navigate that object to have access to ANY property in the data model.

Binding whole elements to data model

Do you know how annoying it is to have to perform a documement.getElementById('myElement'); in your Javascript? Yeah, Peasy-UI makes that a bit easier.

BINDING: ${ ==> propertyName}

Let's look at this timesaver example:

const model = {
  myInputElement: undefined as HTMLElement | undefined,
};

const template = `
myInputElement} />
`;

What this binding does is maps the DOM elements rendered and binds their reference inside the model. In this example, instead of having to do the getElementById() method, model.myInputElement is that reference after the first rendering cycle. The element has to render 'first' then the reference to it gets captured in the data model. This is why its set to undefined by default, then gets set to the element reference after the HTML gets injected into the DOM. So now to have access to the element value, i can just access model.myInputElement.value or any attribute in that element that I'd like access to.

Binding for rendering

What if you want to be selective about what gets rendered and maybe have portions of your template not rendered under certain conditions. Yup, Peasy-UI allows you to control overall rendering as well.

BINDING: ${=== propertyName}

BINDING: ${!== propertyName}

Let's looke at the example of this binding:

const model = {
  isDog: true,
};

const template = `
I am a Dog
I am a Cat

In this example you will only see one of the bound div's being rendered, and by toggling between true and false in the data model.isDog, you can control which div is being rendered.

Binding for arrays

Sometimes you need to list things out in the DOM. Examples may be forum posts, options in a select input, or list items in a nav bar. Peasy-UI gives you an iterable renderer, so you can translate a list or array in the data model to multiple element renderings.

BINDING: ${ item

Let's give a simple example:

const model = {
  myItems: [{text: 'one', value: '1'},{text: 'one', value: '1'},{text: 'one', value: '1'}],
};

const template = `

So this use case iterates over the 'myItems' property array in the data model, and renders a separate option element in the select tag.

Each rendered option tag has its own model scope as you can see, with opt.text and opt.value.

Bindings for components

So with larger projects, there is a desire to organize a code base and utilize code splitting to keep aspects of a project manageable. Peasy-UI allows for component based design. We will 'lightly' touch on this topic in this article as the overall component feature will get its own article for properly exploring its capabilities.

A component in Peasy-UI is any JavaScript object which contains a static, public template property and a static create method.

BINDING: ${ComponentName === state}

Let's look at one basic example, with more to follow in future article:

class MyComponent{
  public static template = `
  
Hello \${name}
My count is: \${count}
`; constructor(public name: string,public count:number){} static create( state: {name:string, count:number}){ return new MyComponent(state.name, state.count) } } const model = { MyComponent, componentData:{ name: 'bob', count: 10, } }; const template = `

So the MyComponent class must have a static create method that accepts incoming state, and a public static template. What Peasy-UI will do is set the local class properties as the internal state for each component, and will inject the class template into the overall project template.

This can let you break a larger project down into smaller pieces. There is a lot more you can do with components, and it warrants its own article to explore further.

Getters

The final binding idea to be covered is the usage of getters in the data model and what they bring to the table. Sometimes a simple primitive just doesn't cut it in the data model, and getters provide a means of providing more complicated logic and the return value will be the binding value to the binding. There's no unique binding tag to cover here, just an example:

const model = {
  val1: 1,
  val2: 3,
  get myGetter(){
      return this.val1   this.val2;
  },
};

const template = `
My getter value is: \${myGetter}

The nice part of using a getter is that it gets re-evaluated every rendering loop. So if any values change within its own logic, it will get updated.

More information

More information can be found in the GitHub repo for Peasy-Lib, you also will find all the other companion packages there too. Also, Peasy has a Discord server where we hang out and discuss Peasy and help each other out.

The author's twitter: Here

The author's itch: Here

Github Repo: Here

Discord Server: Here

Conclusion

So this article covered all the basics of the Peasy-UI library's data bindings, which is the magic that powers how the library is used to render essentially anything you need in the DOM. We discussed Text Bindings and Attribute Bindings. For each we covered the binding syntax, and how it can be used in examples.

In the next article we will dive deeper into events.

版本声明 本文转载于:https://dev.to/jyoung4242/bindings-and-templates-part-2-of-the-peasy-ui-series-k44?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta 中的列偏移发生了什么?
    Bootstrap 4 Beta:列偏移的删除和恢复Bootstrap 4 在其 Beta 1 版本中引入了重大更改柱子偏移了。然而,随着 Beta 2 的后续发布,这些变化已经逆转。从 offset-md-* 到 ml-auto在 Bootstrap 4 Beta 1 中, offset-md-*...
    编程 发布于2024-12-22
  • 如何使用 jQuery 创建动态颜色渐变?
    如何使用 jQuery 创建动态颜色渐变?
    使用 jQuery 实现动态颜色淡入淡出:增强用户焦点的指南动画文本可以有效地吸引用户注意力,但是淡入背景怎么样?颜色来突出显示重要信息?使用 jQuery,这项任务变得毫不费力。使用 jQueryUI 淡入/淡出背景颜色要使用 jQuery 专门为元素的背景颜色设置动画,您需要包含 jQueryU...
    编程 发布于2024-12-22
  • 尽管代码有效,为什么 POST 请求无法捕获 PHP 中的输入?
    尽管代码有效,为什么 POST 请求无法捕获 PHP 中的输入?
    解决 PHP 中的 POST 请求故障在提供的代码片段中:action=''而不是:action="<?php echo $_SERVER['PHP_SELF'];?>";?>"检查 $_POST数组:表单提交后使用 var_dump 检查 $_POST 数...
    编程 发布于2024-12-22
  • 如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 查找今天生日的用户?
    如何使用 MySQL 识别今天生日的用户使用 MySQL 确定今天是否是用户的生日涉及查找生日匹配的所有行今天的日期。这可以通过一个简单的 MySQL 查询来实现,该查询将存储为 UNIX 时间戳的生日与今天的日期进行比较。以下 SQL 查询将获取今天有生日的所有用户: FROM USERS ...
    编程 发布于2024-12-22
  • 为什么我的 Facebook Graph API 从 v2.2 迁移到 v2.3 后失败?
    为什么我的 Facebook Graph API 从 v2.2 迁移到 v2.3 后失败?
    从 v2.2 迁移到 v2.3 后 Facebook Graph API 无法运行升级到 Facebook Graph API v2.3 后,开发人员遇到了某些 API 请求无法返回数据的问题。本文探讨了遇到的具体问题,并根据最新版本 SDK 中引入的更改提供了解决方案。问题描述开发者报告 API ...
    编程 发布于2024-12-22
  • JavaScript 如何在后台工作:了解其单线程性质和异步操作
    JavaScript 如何在后台工作:了解其单线程性质和异步操作
    JavaScript 是网络的支柱,为数十亿网站和应用程序提供动态客户端功能。但您有没有想过 JavaScript 是如何在后台发挥其魔力的?在这篇文章中,我们将深入研究 JavaScript 单线程本质的内部工作原理并探索异步编程的概念。 单线程是什么意思? 当我们说 JavaSc...
    编程 发布于2024-12-22
  • 如何轻松备份和恢复所有 MySQL 数据库?
    如何轻松备份和恢复所有 MySQL 数据库?
    轻松备份和恢复 MySQL 数据库:综合指南管理大量 MySQL 数据库可能令人望而生畏。为了安全的数据保护,创建定期备份至关重要。本综合指南将提供有关如何轻松同时导出和导入所有 MySQL 数据库的分步说明。导出多个数据库利用 mysqldump 实用程序是导出多个数据库的首选方法立刻。使用命令行...
    编程 发布于2024-12-22
  • 如何防止Python实例之间的类数据共享?
    如何防止Python实例之间的类数据共享?
    如何隔离各个实例的类数据为了避免在多个实例之间共享类数据并确保每个实例维护自己的数据,请按照下列步骤操作:在构造函数中声明变量 (__init__ Method)不要在任何方法之外声明类级变量,而是在 init 构造函数方法中定义它们。例如:class a: def __init__(sel...
    编程 发布于2024-12-22
  • 如何从 Windows 上的 C++ 控制台应用程序打印 UTF-8?
    如何从 Windows 上的 C++ 控制台应用程序打印 UTF-8?
    在 Windows 上从 C 控制台应用程序打印 UTF-8使用 Visual Studio 2008 在英语 Windows 系统上开发 C 控制台应用程序时,用户可能会在显示 UTF- 时遇到挑战8 通过cout或wcout正确编码内容。以下是解决此问题的方法:解决方案:解决方案涉及将控制台的输...
    编程 发布于2024-12-22
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    编程 发布于2024-12-22
  • 为什么 Java 的整数常量池在 127 以上表现不同?
    为什么 Java 的整数常量池在 127 以上表现不同?
    问题:127处Java整数常量池行为的分歧简介:The整数常量池是Java中的一种机制,可以优化常见整数值的缓存以提高性能。然而,该池的行为在 127 时出现了变化,引起了开发人员的困惑。理解行为:对于从 -128 到 127 的整数,Java 保证引用相同常量的变量具有相同的引用。Integer ...
    编程 发布于2024-12-22
  • 如何在 Go 中解组具有混合数据类型的 JSON 数组?
    如何在 Go 中解组具有混合数据类型的 JSON 数组?
    解组具有混合数据类型的 JSON 数组解组包含不同数据类型值的 JSON 数组的任务通常会带来挑战。例如,考虑以下 JSON 数组:{["NewYork",123]}问题:首先,需要注意的是提供的 JSON 在语法上不正确。 JSON 对象需要每个值的键,因此正确的表示形式是 {...
    编程 发布于2024-12-22
  • 除了“if”语句之外:还有什么地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    除了“if”语句之外:还有什么地方可以在不进行强制转换的情况下使用具有显式“bool”转换的类型?
    无需强制转换即可上下文转换为 bool您的类定义了对 bool 的显式转换,使您能够在条件语句中直接使用其实例“t”。然而,这种显式转换提出了一个问题:“t”在哪里可以在不进行强制转换的情况下用作 bool?上下文转换场景C 标准指定了四种值可以根据上下文转换为的主要场景bool:语句:if、whi...
    编程 发布于2024-12-22
  • 如何使用 Java 和 JFreeChart 用轴注释 .png 文件?
    如何使用 Java 和 JFreeChart 用轴注释 .png 文件?
    如何使用 Java 用轴注释 .png 文件无需依赖外部软件即可用轴注释 .png 图像。下面是一种利用 Java 内置功能和 JFreeChart 进行高级定制的方法:创建图表基础首先,使用 JFreeChart 的 ChartFactory.createXYLineChart 方法创建图表。这将...
    编程 发布于2024-12-22
  • 新博客系列:Python 人工智能基础知识
    新博客系列:Python 人工智能基础知识
    欢迎来到我的新博客系列,我们将在机器学习的背景下探索 Python 的迷人世界。由于其简单性和提供的强大库,Python 已成为数据科学和机器学习领域的基石。无论您是初学者还是希望提高自己的技能,本系列都将指导您了解 Python 的基础知识,为您的机器学习之旅奠定坚实的基础。 系列...
    编程 发布于2024-12-22

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3