I've been experimenting with Ashley Grant's post: https://bl.ocks.org/AshleyGrant/07e645e46f7cc945b4e43c4ec80c6424
and was wondering if anyone knows how to go one step further and apply a value converter after using the 'dynamicExpression' Binding Behavior. Something like this:
<input type="text" value.bind="model & dynamicExpression:field.expression | formatNumber:'$###,###.00'" />
Thanks,
The documentation here http://aurelia.io/docs/binding/binding-behaviors#introduction states that value converters only observe the values passing by, but behaviors have full access to binding context.
I guess if you rewrite your formatNumber as a behavior - you can chain them.
Related
In angular-dart it is possible to create your own components as can be seen here. If you use custom tags in the html like this:
<rating></rating>
angular will create a component by calling the constructor of the class associated with rating, in this case new RatingComponent() (if i'm not mistaken).
I know you can add attributes for having some control over it, but i was wondering if it is possible to supply your own instances, instead of angular calling the constructor. What if i have a list of buttons in the main controller, how to achieve something like this:
<div ng-repeat='b in ctrl.buttonList'>
<fancy-button instance='b'></fancy-button>
</div>
I have the feeling i'm missing something obvious, but i did search around and couldn't find the answer.
edit (for extra clarification): I think it boils down to if you can or can not influence/bypass the call of the constructor by angular. If it was just about generating the html, its easy to not use the component and just generate the html using the main-controller (like below), but if possible i would like to use a component since it also has shadow-dom for sandboxing the css.
<div ng-repeat='b in ctrl.buttonList'>
<input type='button' class='fancy' value='{{b.label}}'></input>
</div>
You want something like
<div ng-bind-html='ctrl.html'></div>
This way you can provide the html by the controller.
You would have to create your own implementation of NgBindHtmlDirective (just a few lines) though, because the used NodeValidator of ng-bind-html doesn't allow custom tags (yet).
Maybe there are more sophisticated ways but I don't know Angular very well yet.
=== Edit ===
I think what you try to do is not Angularish.
You can ng-repeat over a model that provides values for the attributes of the fancy-button or input.
In the components class you have access to these attributes and can make the behavior and appearance depending on that attributes.
Using ng-bind-html you can create the markup using code if you don't know at development time what kind of tag you want to use.
I followed the example here: Why does <h:inputText required="true"> allow blank spaces? to create a "Global" converter to trim all input fields. However, the converter is not being invoked when input fields are submitted.
#FacesConverter(forClass=String.class)
...
<p:inputText value="#{controller.inputValue}"/>
but when I change to:
#FacesConverter("StringTrimmer")
...
<p:inputText value="#{controller.inputValue}" converter="StringTrimmer"/>
it works.
Using Mojarra 2.1.7 and PrimeFaces 3.2
A converter with a forClass will only be invoked whenever the type of the property is an instance of the specified class. In your particular case, that can only mean that the #{controller.inputValue} is not of type String.
If you checked that the bound variable is of type String and the converter still doesn't get called, you may also check the following:
If the input component is encapsulated inside a composite component, you may have this issue. In that case, converters would not be called correctly, resulting in your custom method to be never reached. Calling the converter explicitly on the input component solves this.
If you add both value="someName" and forClass="someClass" to the #FacesConverter annotation, the forClass attribute will be ignored. This has been reported here.
This didnt work because the inputValue was not actually of type String. Once changed to type String-- it worked.
I see that mvc is finding the names of the variables passed to it from the lambda function in an Html.DisplayFor method:
#Html.HiddenFor(model => myModel.propA.propB)
could generate HTML something like:
<input id="myModel_propA_propB" type="hidden" value="" >
it is obviously using reflection, but it is beyond me. could someone fill me in?
ALSO, is it possible to create an HTML helper function that takes a fully property reference instead of a lambda function to accomplish something similar? ie.
#Html.HiddenFor(myModel.propA.propB)
...and the helper could be passed the full "myModel.propA.propB" reference and not just the value of propB? is a lambda function an odd .net workaround to accomplish this sort of task or is it actually the preferred approach across all programming disciplines.
Actually, it is traversing the Expression tree you pass into helper method in order to get the property names. In practice, it would look something like:
MemberExpression memberExpression = (MemberExpression) expression.Body;
propertyName = memberExpression.Member.Name;
Of course that is not complete - for instance, you would have to walk up the chain of Expressions when there are multiple property invocations in the expression passed in, you would have to account for other expression types being passed in than MemberExpression, etc., etc. - but you get the idea. Remember that an Expression is a code expression represented as data. Also, since MVC is open source, you could look up the exact code they use to arrive at the html name in the sources, if you want.
To address your second question, the answer is no. Passing "just the property" without the lambda (which will be an Expression<Func<T,object>>), will not work, because then the function can only see the value passed in - and nothing about how the calling code arrived at that value.
I'm trying to reduce some repetitive GSP code in my Grails app. The following code works as expected:
<g:textField name="recordValues.0.name" value="${recordValues?.get(0)?.name}"/>
<g:textField name="recordValues.0.age" value="${recordValues?.get(0)?.age}"/>
[edit]recordValues.0.age is actually a Map not a class property, as I originally stated.
However when I try to dynamically set a bunch of these with a list enum, the value attribute is not evaluated:
<g:each in="${fields}" var="prop">
<g:textField name="recordValues.0.${prop}" value="${recordValues?.get(0)?.prop}"/>
</g:each>
It appears the value attribute is looking for the property Map key called "prop" and is not evaluating it as a variable. I've tried recordValues?.get(0)[prop] with and without ? between but it didn't compile.
Is there some dynamic method I can call with the variable as an argument or an even easier solution?
Sorted it myself in the end. Thanks to codespace for making me check the code again and noticing it was a Map I was trying to reference, not an object property. The fact I was using an enum confused the issue as using the regular map.get(var) did not work, I needed map.get(var.name()) instead (maybe I'll encode it as a String field inside the enum to avoid this).
Here's the solution:
<g:each in="${fields}" var="prop">
<g:textField name="recordValues.0.${prop}" value="${recordValues?.get(0)?.get(prop.name())}"/>
</g:each>
I don't really see the need for element to element binding in Silverlight 3 if using MVVM. Won't having one property directly affect another proper cause that property to be untestable?
To me, it makes more sense to do a two way binding to a explicit property defined in the ViewModel.
I agree that the use of MVVM severely deflates the usefulness of element to element binding.
Still, if all you are doing is binding two elements using a ViewModel property... what can you test? You can test that setting a property in the ViewModel sends a PropertyChanged event... but thats about it. Only when something else cares about that value is it useful to test a property like that.
In the simple cases, I can see element2element binding being more efficient and less code.