-
Notifications
You must be signed in to change notification settings - Fork 310
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
Ability to invoke function inside rivets expressions #554
Comments
@stalniy I can only say 👍 Calling functions in rivets expression is one of the most important missing capability IMHO. Before coding it we should be sure to see all consequences
|
I'm in favor of this |
I have to say I do not like this. Having been forced to work on Angular apps, this leads to allot of bad code. In massive projects, I have only ever seen this go sour as it allows people who are not careful to make things incredibly difficult to debug. That being said, It is not a feature that I, or my juniors, need to use. If you can figure out the Coffee Script. I say take a stab at it. My questions, would I would prefer to see, because it matches typical rivets keypath subscription. <span> { formatDate(todo.date, 'hh:mm') }</span> |
@Duder-onomy good point! It's easy to subscribe to function's arguments but when function doesn't have arguments then we will need to specify its dependencies somehow, so that rivets can track them too. This sounds a bit complicated. As far as I know currently computed properties (i.e. functions) with dependencies are supported in this way: <span rv-text="fullName < firstName lastName"></span> var user = {
firstName: 'John',
lastName: 'Does',
fullName: function() {
return this.firstName + ' ' + this.lastName;
}
}; So, despite that this is a bit inconvenient this can be left as it is. So, what we have:
|
Nice, I agree that expressing a computed property via the old rivets syntax However, I think that the concept of formatters expressed as function calls can be improved. Take this formatter I see people do allot: // Will uppercase then pluralize the name.
<span rv-text='user.name | uppercase | pluralize'></span> I imagine if this was expressed as a function call you could either, <span rv-text='uppercase(pluralize(user.name))'></span> Or write a parent function <span rv-text='uppercaseAndPluralize(user.name)'></span> Would love to hear your thoughts on that use case. The only other item I can imaging creating confusion is bi directional formatting or computed properties. <input rv-value='user.name | asDate'> rivets.formatters.asDate = {
read: function(value) {
return // formatted for user to read
},
publish: function(value) {
return // converted to UTC for model.
}
} A bidirectional formatter makes this clear. It has a If you did <input rv-value='asDate(user.name)'> How would you handle this? Anyways, Awesome work. |
To clarify my comment: i'm in favor to implement passing arguments to event handlers like: The other features i think is out of scope of this library |
@Duder-onomy I like as formatters work, so don't plan to change them. @blikblum I do agree with you that the main purpose of this feature should be event handlers but then devs would want to use this inside binders. For example I saw an issue (#366) which asks about ability to hide item inside <div rv-each-todo="todos" rv-show="canShow(todo)"></div> What looks pretty reasonable and handy in my opinion. |
@blikblum @stalniy Agree too, most usefull is in event handlers. I have maybe an idea to handle functions, i must think about it today. I will explain it as soon as it's clear (and if it leads somewhere ;) ) |
Rivets should not execute functions in bindingsI think rivets binding should not call functions automatically before the formatting process. In this example {{ model.obj.delete | myFormatter }} Rivets executes the function What if Rivets didn't auto execute functionsIf Rivets didn't call the function automatically we could imagine a specific formatter for that {{ model.obj.delete | args 'param1' model.param2 | call | myFormatter}}
// Or shorter
{{ model.obj.delete | call 'param1' model.param2 | myFormatter}} The // Returns a new function with arguments
rivets.formatters["args"] = function(fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
return fn.apply(null, args);
};
};
// Calls the function with arguments
Rivets.formatters["call"] = function(fn) {
return fn.apply(null, Array.prototype.slice.call(arguments, 1));
}; Why two formatters
|
Interesting. The elements rivets provides are very flexible If implementation is not hard, i would like to see a more JS canonical syntax (only for events):
|
I updated the fiddle to see if dynamic values are used and also the value of this https://jsfiddle.net/dh8mpe7r/2/ |
JS canonical syntax should be possible, but we see in @Duder-onomy examples that we will have some problems to deal with. Is it worth it? |
Sorry I haven't contributed to this discussion yet, but I have been reading it. Do you guys know about the |
Also, as @Duder-onomy hinted at, we shouldn't be encouraging hard-coding primitive arguments in HTML anyway, it is really dangerous practice to have JS logic in a different place to your JS. If you want to call a function with a specific string, make that decision in your JS, for example by checking the We can already invoke functions in rivets, we can already watch computed properties, we can already check in the function what part of the model we're in by querying the |
@Leeds-eBooks having an ability to invoke functions:
Frankly speaking, I believe this syntax exists as a bit a hacky way of achieving the goal of function invocation. |
@Leeds-eBooks I mainly follow your opinion. We must not add JS-like syntax. But we should authorize function execution with arguments in any binder, not only in events binders. It would be very simple, we just have to remove auto execution of functions. As this auto execution can cause strange behaviour (see issue #557) we should consider it. |
Is this issue still necessary since #582 ? |
I think it isn't, so I'll close. However it makes me think that perhaps there should be a test for the call formatter in |
It's not very hard to implement ability to pass arguments (and watch them) into function in rivets expression. So that, all the methods will have more clear api
Basically we need to add one more
if
insideTypeParser
which will compile and return function. We can restrict this so the implementation won't be very complicated. For example, it's possible to pass only primitives and keypaths. That means we can't pass function invokation as a result. So this is not valid:However I believe even this case can be handled using recursive.
@blikblum, @Leeds-eBooks, @jccazeaux do you think this something useful or overcomplicated?
The text was updated successfully, but these errors were encountered: