-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Experimental @bind support [Discussion] #31
base: master
Are you sure you want to change the base?
Conversation
EDIT: I believe the current rebuild-system could be nicely merged with my suggested bind logic, if vars change blocks get reevaluated, rather than having two separate approaches Something along these lines: if( m.condition != null ) {
var binding = remapBind(m.condition.cond);
if(binding.isBound) {
return macro {
function __onVarChanged() {
if( ${m.condition.cond} ) $b{exprs};
}
$b{binding.exprs};
$e{
if(binding.isBound)
macro registerBind(__onVarChanged, $v{binding.name})
else macro {}
}
__onVarChanged();
};
} else {
return macro if( ${m.condition.cond} ) $b{exprs};
}
} |
…ocessBind` macro function) - moved bind macro call outside of re-evaluation callback
It's a bit difficult to analyze without reading the source code. |
This is only one possible approach. But the idea is always: Give each var in an attribute expression the possibility to trigger a re-evaluation (usually if the value of that field changed in a data model) Edit: Updated the sample a bit class UserModel {
var firstName(default,set):String = "John";
var lastName = "Wayne"; // same logic as firstName
// setters are auto-generated
function set_firstName(v) {
firstName = v;
triggerChange('firstName');
return v;
}
public function onChange(fieldName:String, callback:Void->Void) {
... // register listener
}
}
class DomkitComp {
var SRC = <comp>
<text id="label" text={@bind user.firstName + " " + user.lastName}
</comp>;
public function new(user:UserModel,?parent) {
initComponent();
trace(label.text); // "John Wayne"
user.lastName = "McLane";
trace(label.text); // "John McLane"
}
}
// Compile Macro:
domkit.Macro.processBind = ( expr ) -> {
// Pseudo-Code:
if( expr.isFieldAccess(obj, field) && obj.isOfType(UserModel)) {
return macro {
obj.onChange(field, __onVarChanged); // "__onVarChanged" is defined before and triggers re-evaluation of the attribute expression and assignment to the component property
}
}
return null; // if it's not something we are interested in, leave blank
} Sorry for the formatting, typed this from my phone ;-) |
This PR implements a first draft of a potential built-in data-binding bridge for Domkit components, as mentioned in: #20
EDIT:
I updated the the implementation to do only the following:
@bind
domkit.Macro.bindVar()
macro call. This is done in order to delay replacement to the stage, where full type information is available.__onVarChanged
)bindVar
to a dynamic functionprocessBind
for user land to implement.Users will have to implement
domkit.Macro.processBind
and pass back an expression doing the actual data-binding logic. This logic calls__onVarChanged()
in order to trigger a re-evaluation of the entire attribute expression and have the new value be assigned to the component's property.Pros
@bind
expressions and trigger a re-assignment. This is more in-line with common event driven data-models. Unlike per-expression based registration/callbacks asregisterCheckRebuild
does.Please feel free to make suggestions.