바인딩과 템플릿: Peasy-UI 시리즈 f부
Table of Contents
- Introduction
- Bindings and the Template
-
Text Bindings
- Basic Binding
- Conditional Boolean Text Binding
- One-time Text bindings
-
Attribute Bindings
- Bindings for element attributes
- Bindings for events
- Binding whole elements to data model
- Binding for Rendering
- Binding for Arrays
- Bindings for Components
- Getters
- More information
- 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 = ` <div> Render Me </div> <button> Click </button> `;
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 = ` <div> Hello: \${name}!!!! </div> `; 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 = ` <div> Hello: \${name}!!!! </div> `;
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 = ` <div> I am using \${'Dark mode' = darkMode} \${'Light mode' ! darkMode} now! </div> `;
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 <== propertyName} bind in one direction from the model to the binding
BINDING: ${attribute <=| propertyName} bind in one direction, one-time, from the model to the binding
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 = ` <div> <input type="radio" \${'red' ==> color}>Red</input> <input type="radio" \${'green' ==> color}>Green</input> </div> `;
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 = ` <div> <label>Enter Username: </label> <input type="text" \${value ==> userName}></input> </div> `;
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 = ` <div> <input type="text" \${value <=> userName}>\${userName}</input> </div> `;
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 = ` <div> <button \${click @=> clickHandler}> Click Me! </button> </div> `;
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 = ` <div> <input type="text" \${==> myInputElement} /> </div> `;
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 = ` <div> <div \${=== isDog}> I am a Dog</div> <div \${!== isDog}> I am a Cat</div> </div>
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 <=* propertyArray}
Let's give a simple example:
const model = { myItems: [{text: 'one', value: '1'},{text: 'one', value: '1'},{text: 'one', value: '1'}], }; const template = ` <div> <select> <option \${opt <=* myItems} value="\${opt.value}">\${opt.text}</option> </select> </div>
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 = ` <div> <div> Hello \${name}</div> <div> My count is: \${count}</div> </div> `; 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 = ` <div> <\${MyComponent === componentData}> </div>
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 = ` <div> <span>My getter value is: \${myGetter}</span> </div>
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.
위 내용은 바인딩과 템플릿: Peasy-UI 시리즈 f부의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

Python은 부드러운 학습 곡선과 간결한 구문으로 초보자에게 더 적합합니다. JavaScript는 가파른 학습 곡선과 유연한 구문으로 프론트 엔드 개발에 적합합니다. 1. Python Syntax는 직관적이며 데이터 과학 및 백엔드 개발에 적합합니다. 2. JavaScript는 유연하며 프론트 엔드 및 서버 측 프로그래밍에서 널리 사용됩니다.

웹 개발에서 JavaScript의 주요 용도에는 클라이언트 상호 작용, 양식 검증 및 비동기 통신이 포함됩니다. 1) DOM 운영을 통한 동적 컨텐츠 업데이트 및 사용자 상호 작용; 2) 사용자가 사용자 경험을 향상시키기 위해 데이터를 제출하기 전에 클라이언트 확인이 수행됩니다. 3) 서버와의 진실한 통신은 Ajax 기술을 통해 달성됩니다.

실제 세계에서 JavaScript의 응용 프로그램에는 프론트 엔드 및 백엔드 개발이 포함됩니다. 1) DOM 운영 및 이벤트 처리와 관련된 TODO 목록 응용 프로그램을 구축하여 프론트 엔드 애플리케이션을 표시합니다. 2) Node.js를 통해 RESTFULAPI를 구축하고 Express를 통해 백엔드 응용 프로그램을 시연하십시오.

보다 효율적인 코드를 작성하고 성능 병목 현상 및 최적화 전략을 이해하는 데 도움이되기 때문에 JavaScript 엔진이 내부적으로 작동하는 방식을 이해하는 것은 개발자에게 중요합니다. 1) 엔진의 워크 플로에는 구문 분석, 컴파일 및 실행; 2) 실행 프로세스 중에 엔진은 인라인 캐시 및 숨겨진 클래스와 같은 동적 최적화를 수행합니다. 3) 모범 사례에는 글로벌 변수를 피하고 루프 최적화, Const 및 Lets 사용 및 과도한 폐쇄 사용을 피하는 것이 포함됩니다.

Python과 JavaScript는 커뮤니티, 라이브러리 및 리소스 측면에서 고유 한 장점과 단점이 있습니다. 1) Python 커뮤니티는 친절하고 초보자에게 적합하지만 프론트 엔드 개발 리소스는 JavaScript만큼 풍부하지 않습니다. 2) Python은 데이터 과학 및 기계 학습 라이브러리에서 강력하며 JavaScript는 프론트 엔드 개발 라이브러리 및 프레임 워크에서 더 좋습니다. 3) 둘 다 풍부한 학습 리소스를 가지고 있지만 Python은 공식 문서로 시작하는 데 적합하지만 JavaScript는 MDNWebDocs에서 더 좋습니다. 선택은 프로젝트 요구와 개인적인 이익을 기반으로해야합니다.

개발 환경에서 Python과 JavaScript의 선택이 모두 중요합니다. 1) Python의 개발 환경에는 Pycharm, Jupyternotebook 및 Anaconda가 포함되어 있으며 데이터 과학 및 빠른 프로토 타이핑에 적합합니다. 2) JavaScript의 개발 환경에는 Node.js, VScode 및 Webpack이 포함되어 있으며 프론트 엔드 및 백엔드 개발에 적합합니다. 프로젝트 요구에 따라 올바른 도구를 선택하면 개발 효율성과 프로젝트 성공률이 향상 될 수 있습니다.

C와 C는 주로 통역사와 JIT 컴파일러를 구현하는 데 사용되는 JavaScript 엔진에서 중요한 역할을합니다. 1) C는 JavaScript 소스 코드를 구문 분석하고 추상 구문 트리를 생성하는 데 사용됩니다. 2) C는 바이트 코드 생성 및 실행을 담당합니다. 3) C는 JIT 컴파일러를 구현하고 런타임에 핫스팟 코드를 최적화하고 컴파일하며 JavaScript의 실행 효율을 크게 향상시킵니다.

Python은 데이터 과학 및 자동화에 더 적합한 반면 JavaScript는 프론트 엔드 및 풀 스택 개발에 더 적합합니다. 1. Python은 데이터 처리 및 모델링을 위해 Numpy 및 Pandas와 같은 라이브러리를 사용하여 데이터 과학 및 기계 학습에서 잘 수행됩니다. 2. 파이썬은 간결하고 자동화 및 스크립팅이 효율적입니다. 3. JavaScript는 프론트 엔드 개발에 없어서는 안될 것이며 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축하는 데 사용됩니다. 4. JavaScript는 Node.js를 통해 백엔드 개발에 역할을하며 전체 스택 개발을 지원합니다.
