Ignition Bindings Deep Dive
Bindings are some of the first things you will encounter in any Ignition project. There are many types of bindings to accomplish different goals. In most cases, bindings are easy to understand and implement. But, as you work on more complex projects (and your experience with Ignition grows) you will start to see that you can have many choices in your strategy for getting the job done.
In this post, we’ve compiled our best practices for the most common binding types in both Vision and Perspective. We hope you find our advice helpful, and that it saves you from relying on trial and error. Learn more about Corso Systems’ work with Ignition—and how we can help your manufacturing company.
Tag Bindings
Avoid the tag() expression function. Prefer indirect tag bindings.
Instead of:
Use this Indirect Tag Binding:
Because:
Using an indirect tag binding is clearer and considerably more performant. See this forum post (among others) for discussion.
Instead of using an Expression binding on a TextField:
Use an Indirect Tag Binding, since this allows a Bidirectional option:
Because:
Expression bindings can't be bidirectional. The bidirectional indirect tag binding can—which is required to write back to the tag from the control.
Don't bind to .value because it's implied.
Instead of using an Expression binding to bind to .value:
Use an Indirect Tag Binding (.value is implied):
Because:
Using an expression binding to bind to .value is unnecessary, and adds a few keystrokes or clicks - which can be opportunities for error.
Property Bindings
Avoid Expression bindings. Prefer property bindings.
Instead of:
Do:
Because:
It's more clear and takes less mental overhead to grok that the expression simply resolves to a property reference. It is a property to property binding; there is no reason to bring an expression into the fold. Additionally, it affords the opportunity to make the binding bidirectional.
Expression Bindings
Break longer expressions into multiple lines.
Instead of:
Do:
Because:
An expression that is broken up on multiple lines is easier to read, write, and troubleshoot.
Break complex expressions into multiple custom properties with meaningful names.
Instead of:
Instead, break up the expression into multiple custom properties with descriptive, meaningful names :
We recommend this approach because:
The expressions are easier to read, write, and troubleshoot.
Any calculated values used more than once (such as custom.calcs.runTimeMins) are only evaluated once.
The calculations are independent of the View's component hierarchy (see custom.inputs). This allows for refactoring of the View's layout with minimal impact to the functionality.
Notes:
The choice to use an "Expression Structure" binding on custom.inputs helps facilitate refactoring and understanding the View at first glance. There is only "one place" to handle bindings to user input controls. This could have been a series of individual bindings but that would mean "more places". There isn't much of a performance difference (if any).
Notes Continued: custom.calcs and custom.values are not Expression Structures because some members reference other values within the same structure (e.g., custom.values.oee)
Overwhelmed? Corso Systems can help!
Schedule a call with Cody Johnson in Sales today, we KNOW Ignition!
Expression Structure Bindings
"Roll up" multiple values into a single object for further processing.
The primary reason for using Expression Structures is that they can combine multiple distinct values into a single object that can be processed as a single entity. In the following example, changes to either Numeric Input value will cause the expression structure binding and subsequent script transform to resolve.
Query Bindings
Avoid inline queries. Prefer Named Queries or centralized DB scripts.
Putting raw SQL inside a View or Window is a violation of the Separation of Concerns Principle. It can be difficult to maintain a project with queries embedded inside UI components.
Avoid polling when possible. Prefer refreshBinding().
Polling the database, while necessary at times, can become a performance concern at scale. Try to use an "event based" approach to refetching data from a database. For example, if another user in a different session has created a change in the underlying data, use session messaging to inform other sessions they need to refresh or refresh the binding automatically.
Cache & Share when appropriate.
Caching is appropriate when the data is accessed frequently but changes infrequently. Relatively static tables, such as an equipment table or a user roster are not likely to change within the span of a cache's lifetime. However, real-time data such as equipment state changes frequently enough that caching may result in misleading data.
Tag History Bindings
Follow database/query binding best practices.
A tag history binding is essentially a guided query. Follow general best practices for polling and caching.
HTTP Bindings
Follow database/query binding best practices.
HTTP Bindings are IO (Network) intensive. Follow general best practices for polling and caching.
Wrapping Up
We hope this guide was useful for you! If there any Ignition topics, Vision, Perspective, general architecture, or anything you wish to see as a tutorial on our website, reach out and let us know!