How can I use window size in Vue? (How do I detect the soft keyboard?)
The link above is an excellent answer but I don't understand what this (`) mark is and why the values for newHeight, oldHeight are passed in. Also why this syntax ${somevariable} in the watcher works.
windowHeight(newHeight, oldHeight)
this.txt = it changed to ${newHeight} from ${oldHeight};
...
The "backtick" syntax is not Vue specific, but it's a javascript language feature called Template literals. It's quite easy though: when you write a string like this:
const what = "world";
const salutation = `Hello ${what}`;
the value of salutation will be "Hello world". When the expression is evaluated, the interpreter swaps the ${what} with the actual content of the what variable.
You can learn more about template literals on MDN.
In the linked answer, it's used as a simple debug method to show what's going on.
Related
I want to create a Live Template for createSelector:
export const someSelector = createSelector(getThis, getThat, getSomethingElse, (this, that, somethingElse) =>
$END$
)
I can get it to work pretty well with a single argument (e.g., only getThis which then results in (this) in the arrow function args).
// template text
createSelector($someSelector$, ($variable$) => $END$)
// variables
// expression for "variable":
decapitalize(regularExpression(someSelector, "get", ""))
This works correctly with a single argument as mentioned above, and almost works correctly with multiple arguments, except for the capitalization:
createSelector(getThis, getThat, getSomethingElse, (this, That, SomethingElse) => /* $end$ */)
I tried wrapping that whole thing in camelCase but then of course the commas and spaces are gone.
The issue is clearly that I'm processing the whole string at once so the whole string is run through whatever string formatting function. There doesn't appear to be any way to treat individual instances of "get" separately.
I tried capture groups which I really thought would work:
decapitalize(regularExpression(someSelector, "get(\w+)", "$1"))
But that doesn't replace anything, it just copies the whole thing:
createSelector(getThis, getThat, (getThis, getThat) => )
Is there any way to accomplish this?
UPDATE:
I even learned Groovy script and wrote the following, which works in a groovy playground, but gets in WebStorm gets the same result as my final example above!
groovyScript("return _1.replaceAll(/get(\w+)/) { it[1].uncapitalize() };", someSelector)
This could be done with RegEx .. but Java does not seem to support \l replacement modifier (to be used as \l$1 instead of $1 in your initial regularExpression() code).
Live example (works in PCRE2, e.g. in PHP): https://regex101.com/r/6faVqC/1
Docs on replacement modifiers: https://www.regular-expressions.info/refreplacecase.html
In any case: this whole thing is handled by Java and you are passing RegEx pattern or GrovyScript code inside double quotes. Therefore any \ symbols would need to be escaped.
You need to replace get(\w+) by get(\\w+).
The following seems to work just fine for me here (where someSelector is the Live Template variable):
groovyScript("return _1.replaceAll(/get(\\w+)/) { it[1].uncapitalize() };", someSelector)
Why this "value" can not be written as "pricevalue" or other, otherwise input will not convert non-numeric values
In the props element, you are defining the properties your component will attach to. You can call them whatever you want. You need to be clear about a couple of things...
You define the name here in camelCase, but when you call the component in the parent markup, use kebab-case.
methods only run when they are called. If you put your formatting on the downstream side (receiving a value and displaying it), everything will be reactive and all your values should display correctly. It will all just work whenever the source value changes. So do your formatting in a computed, like this...
js
computed: {
formattedPriceValue(){
return Number.parseFloat(this.priceValue).toFixed(2)
}
}
You can also just do it inline...
markup
<input type="number" :value="Number.parseFloat(priceValue).toFixed(2)">
The value you want to emit is probably the unformatted output of Number.parseFloat #change="$emit('price-changed', Number.parseFloat(event.target.value))"
Then, you will live longer if you do your number formatting with the Number functions provided.
Also, why don't you use the new template (multi-line) strings, delimited by a backtick `. They're much cleaner than the line continuation character you're using.
ps. I love seeing the chinese (?) comments in the code. I've copied and pasted them into my code. I hope there's no swearing. Unicode rocks.
Is it possible, in ABAP, to evaluate string templates dynamically?
Normally, you will have some string template in code that will be checked by the compiler. (The variables in the curly brackets are checked by the compiler at compile time).
However, is it possible to have a string evaluated at runtime?
So, instead of:
data(val) = |System ID: { sy-sysid }|.
I would like the string to be interpolated to come from elsewhere, for example:
parameter: p_file type string lower case default '/mnt/{ sy-sysid }/file.txt'.
In this case, I would like to have the value of p_file to be evaluated at runtime to substitute the variable (sy-sysid) with the runtime value.
You could, of course, program your own substitution by finding all occurrences of variables with curly brackets with a regex expression, then evaluate the variable values with ASSIGN and substitute them back into the string, but I am looking for a built-in way to do this.
Sorry, this is maybe a stupid example, but hopefully you understand what I mean. (If not, please let me know in the comments and I will try and clarify).
The problem in your snippet is not with string template but with PARAMETER behavior. It does not allow dynamics in DEFAULT clause.
To achieve what you want you should use INITIALIZATION and set path value in runtime:
parameter: p_file type string lower case.
INITIALIZATION.
p_file = | /mnt/{ sy-sysid }/file.txt |.
Unfortunately, the example you gave, does not make any sense to me. ABAP String templates are evaluated at run-time and type-checked at compile-time.
In your example, it is always the run-time value of SY-SYSID that will be written to the variable.
I guess what you want to do is circumvent compile-time checks for expressions inside a string template.
Please try to give us your actual use case, so maybe we find an even better solution to your problem.
However, here is what I think could help you:
Personally, I do not recommend to write code like the one below, because it is extremely error-prone likely to mislead other programmers and because there is very likely a better solution.
Given that you know the name of a variable at run-time, try this:
".. say LV_VARNAME is a charlike variable that contains a
" variable name at runtime.
"NOTE that the variable LV_VARNAME must be visible in the scope of the
"following code.
FIELD-SYMBOLS: <my_var> TYPE any.
ASSIGN (lv_varname) TO <my_var>.
DATA(lv_str) = |The value is { <my_var> }|.
The title pretty much sums it up, but here's the long version anyway.
After posting a small snippet of perl code, I was told to avoid indirect object notation, "as it has several side effects". The comment referenced this particular line:
my $some_object = new Some::Module(FIELD => 'value');
As this is how I've always done it, in an effort to get with the times I therefore ask:
What's so bad about it? (specifically)
What are the potential (presumably negative) side effects?
How should that line be rewritten?
I was about to ask the commenter, but to me this is worthy of its own post.
The main problem is that it's ambiguous. Does
my $some_object = new Some::Module(FIELD => 'value');
mean to call the new method in the Some::Module package, or does it mean to call the new function in the current package with the result of calling the Module function in the Some package with the given parameters?
i.e, it could be parsed as:
# method call
my $some_object = Some::Module->new(FIELD => 'value');
# or function call
my $some_object = new(Some::Module(FIELD => 'value'));
The alternative is to use the explicit method call notation Some::Module->new(...).
Normally, the parser guesses correctly, but the best practice is to avoid the ambiguity.
What's so bad about it?
The problems with Indirect Method Notation are avoidable, but it's far easier to tell people to avoid Indirect Method Notation.
The main problem it's very easy to call the wrong function by accident. Take the following code, for example:
package Widget;
sub new { ... }
sub foo { ... }
sub bar { ... }
sub method {
...;
my $o = new SubWidget;
...;
}
1;
In that code, new SubWidget is expected to mean
SubWidget->new()
Instead, it actually means
new("SubWidget")
That said, using strict will catch most of these instances of this error. Were use strict; to be added to the above snippet, the following error would be produced:
Bareword "SubWidget" not allowed while "strict subs" in use at Widget.pm line 11.
That said, there are cases where using strict would not catch the error. They primarily involve the use of parens around the arguments of the method call (e.g. new SubWidget($x)).
So that means
Using Indirect Object Notation without parens can result in odd error messages.
Using Indirect Object Notation with parens can result in the wrong code being called.
The former is bearable, and the latter is avoidable. But rather than telling people "avoid using parens around the arguments of method calls using Indirect Method Notation", we simply tell people "avoid using Indirect Method Notation". It's just too fragile.
There's another issue. It's not just using Indirect Object Notation that's a problem, it's supporting it in Perl. The existence of the feature causes multiple problems. Primarily,
It causes some syntax errors to result in very odd/misleading error messages because the code appeared to be using ION when it wasn't.
It prevents useful features from being implemented since they clash with valid ION syntax.
On the plus side, using no indirect; helps the first problem.
How should that line be rewritten?
The correct way to write the method call is the following:
my $some_object = Some::Module->new(FIELD => 'value');
That said, even this syntax is ambiguous. It will first check if a function named Some::Module exists. But that's so very unlikely that very few people protect themselves from such problems. If you wanted to protect yourself, you could use the following:
my $some_object = Some::Module::->new(FIELD => 'value');
As to how to avoid it: There's a CPAN module that forbids the notation, acting like a pragma module:
no indirect;
http://metacpan.org/pod/indirect
The commenter just wanted to see Some::Module->new(FIELD => 'value'); as the constructor.
Perl can use indirect object syntax for other bare words that look like they might be methods, but nowadays the perlobj documentation suggests not to use it.
The general problem with it is that code written this way is ambiguous and exercises Perl's parser to test the namespace to e.g. check when you write method Namespace whether Namespace::method exists.
Dojo's dijit html5 tags use an attribte name data-dojo-props. The value is basically a JSON string without quotes around the property names and without the outermost braces.
It looks something like this.
data-dojo-props="prop1:'xyz', prop2:true, prop3: { subprop1: 1, subprop2: 'abc'}"
I'm using C# to write this out from a C# object using JSON.NET and passing in the object pointer. I found settings to leave out the property name quotes, but I can't figure out a graceful way to remove the outside braces.
For now, I'll run the string through a regex to remove them, but was wondering if someone new a better way.
I serialize each top level property separately and make it a global javascript variable. I then reference that variable in data-dojo-props. I admit it's not that elegant.
My concern with your approach above, is if the value of subprop2 contains a quote, you will get a parser error.
<script type="text/javascript">
menuData = {THE SERIALIZED JSON GOES HERE};
</script>
<div data-dojo-type="SomeWidget" data-dojo-props="menuData: menuData"></div>