ng-interactions
v1.0.19
Published
Experimental library for Angular that let you code in HTML!
Downloads
5
Readme
Angular Interactions
This is an experimental library for Angular. The main purpose is to provide a discriptive language using HTML tags. Consists of Triggers and Actions.
Setup
- install via npm:
npm i ng-interactions@latest --save
- Import NgInteractionsModule in you module
import { NgInteractionsModule } from "ng-interactions";
@NgModule({
imports: [
NgInteractionsModule,
....
]
})
export class AppModule { }
Triggers
1. Event Trigger:
Event Trigger will subscribe to an event of a given object, and will execute the actions when the event fires:
<event-trigger on="click" element="#element-id">
...actions go here...
</event-trigger>
Or
<event-trigger on="click" [element]="element">
...actions go here...
</event-trigger>
Or
<button>
<event-trigger on="click">
...actions go here...
</event-trigger>
Click me!
</button>
element
: property can be an HTML Element or an object. if element
was not provided, default element will be the parent of event-trigger
.
on
: property is a name of a known HTML event or an observable member in element
.
2. State Trigger:
State Trigger fires when the condition changes to true. You can provide either (value1), (value2) or (value1, oper, value2):
<state-trigger [value1]="object" oper="===" value2="some value">
...actions go here...
</state-trigger>
<state-trigger [value1]="value">
...actions go here...
</state-trigger>
<state-trigger [value2]="value">
...actions go here...
</state-trigger>
Actions
Action is like a block of code that can be executed.
All actions have delay
property to delay the execution, you can pass a number (in ms) or a Date.
All actions have param
property to pass parameters from Angular scope to your code scope, see Custom Binding section.
1. css
element
property can be a string to query (#id, .class...) or an HTML element.
<css element="#cover" property="height" value="10px" [delay]="300"></css>
2. css-class
<css element="#cover" add="class-to-add" remove="class-to-remove" toggle="class-to-toggle"></css>
3. css-translate
<css-translate element="#cover" property="x" value="100px"></css-translate>
4. css-rotate
<css-rotate element="#cover" property="z" value="90px"></css-rotate>
5. css-scale
<css-scale element="#cover" property="x" value="90px"></css-scale>
6. css-skew
<css-skew element="#cover" property="z" value="90px"></css-skew>
7. css-matrix
TODO
8. exec
<exec [source]="object" function="someFunction" [params]="[]"></exec>
You can pass a callback parameter like this:
<exec function=":setTimeout" [params]="[,500]">
<callback-param index="0"> <!-- index="0" is the default -->
acctions...
</callback-param>
</exec>
9. func
TODO
10. set
<set [target]="object" property="prop" value="value..."></set>
11. if
if
condition can be set by providing either (value1), (value2) or (value1, oper, value2):
<if [value1]="object" oper=">" value2="50">
<then>
body goes here...
</then>
<else>
else goes here...
</else>
</if>
<if [value1]="object">
</if>
<if [value2]="object">
</if>
<if value1=":$param">
</if>
<if value1=":param1 > param2">
</if>
12. switch
<switch [value]="state">
<case value="a">
case 'a' body goes here...
</case>
<case value="b">
case 'b' body goes here...
</case>
<case value="c">
case 'c' body goes here...
</case>
</switch>
13. counter
indexVar
default value is $index
from
default value is 0
by
default value is 1
<counter [from]="from" [to]="to" [by]="by" indexVar="i">
<if value1=":i % 2 === 0">
<then>
<exec function=":console.log" params=":[i]"></exec>
</then>
</if>
</counter>
14. foreach
itemVar
default value is $item
.
indexVar
default value is $index
.
<foreach [items]="data" itemVar="item" indexVar="i">
<if value1=":i % 2 === 0">
<then>
<exec function=":console.log" params=":[i, item]"></exec>
</then>
</if>
</foreach>
15. while
<while [value]="value">
...
</while>
Custom Binding
You can always use Angular binding (e.g. [value1]="value") with any property in any action or trigger.
Using Angular binding may become a performance issue, instead, you can use prop=":rest of code..."
to use a simple binding that evaluates only when needed.
Example:
<if value1=":index === 0">
...
</if>
Unlike Angular, the code after :
can't access variables outside the scope, only can access variables that passed in [param]
attribute.
Example of passing param:
<if value1=":h > 0 && h < 200" [param]="{ h: formGroup.controls['height'].value }">
<css-translate property="y" element="#element-id" value=":h"></css-translate>
</if>
Extending Triggers
Trigger is an Angular Component, inherted from TriggerBase.
Example:
import { Component } from '@angular/core';
import { TriggerBase } from 'ng-interactions';
@Component({
selector: 'my-trigger',
template: ''
})
export class MyCustomTrigger extends TriggerBase {
constructor() {
super();
}
protected onLoad() {
// trigger loaded === ngAfterViewInit()
}
when_you_need_to_execute_actions() {
this.fire(params);
}
}
Extending Actions
Action is an Angular Component inherted from ActionBase
, and implements executeInternal
function.
Don't forget to add providers
to be discoverable and executed automatically.
Example:
import { Component, forwardRef } from '@angular/core';
import { ActionBase } from 'ng-interactions';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/empty';
@Component({
selector: 'my-action',
template: '',
providers: [{provide: ActionBase, useExisting: forwardRef(() => MyCustomAction) }]
})
export class MyCustomAction extends ActionBase {
constructor() {
super();
}
@Input() myProp: any;
protected executeInternal(params: any): Observable<any> {
// custom implementation goes here...
// call tryExecuteCode to evaluate code from myProp (e.g. myProp=":user code...").
let value = this.tryExecuteCode(params, this.myProp);
// use `value` as you want.
// call extendParams to extend parameters to
params = this.extendParams(params);
let value = this.tryExecuteCode(params, this.myProp);
return Observable.empty();
}
}