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

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

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

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]删除
最新教程 更多>
  • 为什么Microsoft Visual C ++无法正确实现两台模板的实例?
    为什么Microsoft Visual C ++无法正确实现两台模板的实例?
    The Mystery of "Broken" Two-Phase Template Instantiation in Microsoft Visual C Problem Statement:Users commonly express concerns that Micro...
    编程 发布于2025-07-08
  • Spark DataFrame添加常量列的妙招
    Spark DataFrame添加常量列的妙招
    在Spark Dataframe ,将常数列添加到Spark DataFrame,该列具有适用于所有行的任意值的Spark DataFrame,可以通过多种方式实现。使用文字值(SPARK 1.3)在尝试提供直接值时,用于此问题时,旨在为此目的的column方法可能会导致错误。 df.withCo...
    编程 发布于2025-07-08
  • 在PHP中如何高效检测空数组?
    在PHP中如何高效检测空数组?
    在PHP 中检查一个空数组可以通过各种方法在PHP中确定一个空数组。如果需要验证任何数组元素的存在,则PHP的松散键入允许对数组本身进行直接评估:一种更严格的方法涉及使用count()函数: if(count(count($ playerList)=== 0){ //列表为空。 } 对...
    编程 发布于2025-07-08
  • Java数组中元素位置查找技巧
    Java数组中元素位置查找技巧
    在Java数组中检索元素的位置 利用Java的反射API将数组转换为列表中,允许您使用indexof方法。 (primitives)(链接到Mishax的解决方案) 用于排序阵列的数组此方法此方法返回元素的索引,如果发现了元素的索引,或一个负值,指示应放置元素的插入点。
    编程 发布于2025-07-08
  • Java中Lambda表达式为何需要“final”或“有效final”变量?
    Java中Lambda表达式为何需要“final”或“有效final”变量?
    Lambda Expressions Require "Final" or "Effectively Final" VariablesThe error message "Variable used in lambda expression shou...
    编程 发布于2025-07-08
  • 如何简化PHP中的JSON解析以获取多维阵列?
    如何简化PHP中的JSON解析以获取多维阵列?
    php 试图在PHP中解析JSON数据的JSON可能具有挑战性,尤其是在处理多维数组时。 To simplify the process, it's recommended to parse the JSON as an array rather than an object.To do...
    编程 发布于2025-07-08
  • 在C#中如何高效重复字符串字符用于缩进?
    在C#中如何高效重复字符串字符用于缩进?
    在基于项目的深度下固定字符串时,重复一个字符串以进行凹痕,很方便有效地有一种有效的方法来返回字符串重复指定的次数的字符串。使用指定的次数。 constructor 这将返回字符串“ -----”。 字符串凹痕= new String(' - ',depth); console.Wr...
    编程 发布于2025-07-08
  • 如何使用不同数量列的联合数据库表?
    如何使用不同数量列的联合数据库表?
    合并列数不同的表 当尝试合并列数不同的数据库表时,可能会遇到挑战。一种直接的方法是在列数较少的表中,为缺失的列追加空值。 例如,考虑两个表,表 A 和表 B,其中表 A 的列数多于表 B。为了合并这些表,同时处理表 B 中缺失的列,请按照以下步骤操作: 确定表 B 中缺失的列,并将它们添加到表的末...
    编程 发布于2025-07-08
  • 左连接为何在右表WHERE子句过滤时像内连接?
    左连接为何在右表WHERE子句过滤时像内连接?
    左JOIN CONUNDRUM:WITCHING小时在数据库Wizard的领域中变成内在的加入很有趣,当将c.foobar条件放置在上面的Where子句中时,据说左联接似乎会转换为内部连接。仅当满足A.Foo和C.Foobar标准时,才会返回结果。为什么要变形?关键在于其中的子句。当左联接的右侧值...
    编程 发布于2025-07-08
  • 您如何在Laravel Blade模板中定义变量?
    您如何在Laravel Blade模板中定义变量?
    在Laravel Blade模板中使用Elegance 在blade模板中如何分配变量对于存储以后使用的数据至关重要。在使用“ {{}}”分配变量的同时,它可能并不总是最优雅的解决方案。幸运的是,Blade通过@php Directive提供了更优雅的方法: $ old_section =“...
    编程 发布于2025-07-08
  • 如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    如何从Python中的字符串中删除表情符号:固定常见错误的初学者指南?
    从python import codecs import codecs import codecs 导入 text = codecs.decode('这狗\ u0001f602'.encode('utf-8'),'utf-8') 印刷(文字)#带有...
    编程 发布于2025-07-08
  • 如何从Google API中检索最新的jQuery库?
    如何从Google API中检索最新的jQuery库?
    从Google APIS 问题中提供的jQuery URL是版本1.2.6。对于检索最新版本,以前有一种使用特定版本编号的替代方法,它是使用以下语法:获取最新版本:未压缩)While these legacy URLs still remain in use, it is recommended ...
    编程 发布于2025-07-08
  • PHP与C++函数重载处理的区别
    PHP与C++函数重载处理的区别
    作为经验丰富的C开发人员脱离谜题,您可能会遇到功能超载的概念。这个概念虽然在C中普遍,但在PHP中构成了独特的挑战。让我们深入研究PHP功能过载的复杂性,并探索其提供的可能性。在PHP中理解php的方法在PHP中,函数超载的概念(如C等语言)不存在。函数签名仅由其名称定义,而与他们的参数列表无关。...
    编程 发布于2025-07-08
  • 使用jQuery如何有效修改":after"伪元素的CSS属性?
    使用jQuery如何有效修改":after"伪元素的CSS属性?
    在jquery中了解伪元素的限制:访问“ selector 尝试修改“:”选择器的CSS属性时,您可能会遇到困难。 This is because pseudo-elements are not part of the DOM (Document Object Model) and are th...
    编程 发布于2025-07-08
  • HTML格式标签
    HTML格式标签
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    编程 发布于2025-07-08

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

Copyright© 2022 湘ICP备2022001581号-3