Is it possible to create a tag function when the template literal is a variable?
e.g. instead of this
render`<h1>Hello World</h1>`
Is there any way to do this?
const template = `<h1>Hello World</h1>`
render(template)
No, that's not possible. Tagged templates are a special syntax where render will get called with a string array and all the ${value} values. By storing it in a variable like that, the template literal is instead interpreted as a regular template literal to be converted to a string instead of a function call.
Of course, if all your render function does is concatenation of the template and its variables, it doesn't matter. But mind that the variables inside the template literal are already evaluated when you store it in a variable, it can't get re-evaluated later.
Related
I'm trying to use th:onclick to call a submit() on form whose ID is given as Thymeleaf variable. I write:
th:fragment="fragGname(formname)"
......
th:onclick="'document.getElementById(\'' + ${formname} + '\').submit();'">
But I receive the error
org.thymeleaf.exceptions.TemplateProcessingException: Only variable expressions returning numbers or booleans are allowed in this context, any other datatypes are not trusted in the context of this expression, including Strings or any other object that could be rendered as a text literal. A typical case is HTML attributes for event handlers (e.g. "onload"), in which textual data from variables should better be output to "data-*" attributes and then read from the event handler.
Where is the mistake? Thanks!
I got it:
th:onclick="document.getElementById([[${formname}]]).submit();"
I currently have an object which I want to pass as a parameter to another function inside a template literal:
var template = `<button onclick="onclick(${object})"></button>`;
However, this makes the parameter become a string value: [object Object] and doesn't pass the parameter. Is there any way to pass this parameter into the function?
Thank you very much in advance.
You are going to need to represent your object as a string. You can do this using JSON.stringify:
var template = `<button onclick="handleClick(${JSON.stringify(obj).split('"').join(""")})"></button>`;
You will need to escape double quotes (which this code does), and single quotes if used for your onclick event (this code doesn't).
onclick="onclick" actually calls window.onclick - meaning that it picks up clicks anywhere. You should use a different name (such as handleClick).
I would suggest refraining from using inline event listeners for reasons like this, and because they can cause issues if you ever need to adopt a content-security-policy.
I am programming a web-component with lit-element and wonder, how I can render a string inside of a variable which still has intact #click listeners with the html "processor" instead of the pure string.
someFunction() {
var someString=`<button #click="alert('hi')">blah</button>`;
return html([someString]);
}
render() {
return this.someFunction();
}
doesn't work, while
someFunction() {
return html`<button #click="alert('hi')">blah</button>`
}
render() {
return this.someFunction();
}
works.
Thanks for your help!
That is not possible. These are two tagged template literal and function call fundamentally different things:
Tagged template literal
html`<button #click="alert('hi')">blah</button>`
Calling html as a tagged template function will call html function with n-argument parameters. First will be an array of the constant part of the template and arguments from second onwards will be interpolated valued.
Ordinary function call
const someString = `<button #click="alert('hi')">blah</button>`;
html([someString]);
Calling html as a function html([someString]) will call that function with array as its first argument.
Being a language feature, the browser needs to understand a tagged template from ordinary function. It happens at a lexical/syntactical level and thus a tagged function must and must be followed by backtick(`) character.
In summary, tagged function html cannot exist without backtick. You can read more here on MDN docs.
"Angular directive attributes take either expressions or interpolation markup with embedded expressions. It is considered bad practice to embed interpolation markup inside an expression".
I couldn't understand the difference between expressions and interpolation markup with embedded expressions. Please can someone explain ? I am new to angular.I checked the documentation but couldn't find the difference.
An expression would be the "myscope" in ng-model="myscope"
And you can also do custom attributes like my-att="{{myscope}}"
edit: these expressions in curly braces are interpolated, meaning not the expression itself but its value gets passed into the directive. Your directive will thereby not have direct access to the scope property you used for the interpolation.
But you should not mix the two like ng-model="my{{scope}}"
I think that is what it refers to. This will often not work, since the scope is not yet initialized when the directive is parsed
Expression refers to Angular expression that may or may not contain double curly braces whereas interpolation markup means code inside this curly braces.
Expression {{exp}}: Something that turns into some value.
Characteristics:
It is processed by angular.
Angular expression are tied to the scope they are in. It has access to the properties of $scope.
Doesn't throws error if it has type error.
Control flow function(e.g., 'If', 'else' statement etc) not allowed.
Accept filter or a filter chain to format the output.
Interpolation (process): Process of replacing placeholders in a string with values.
Characteristics:
In Angular, these placeholders are usually expressions.
Result is automatically updated when placeholder changes. If $scope.message changes so will interpolation result will change.
Ex:
My name is {{ message }}
It is interpolated to: My name is Harry Potter
As you know, a single String can define many key/value properties. For instance, a query String can be defined as
someKey=someValue&anotherKey=anotherValue
Now i need to define a pattern in which a single String can define many key/value properties to be stored in a class attribute. But each value can be a String, an Array, A reference to a JavaScript function etc. Something like (Hypothetical pattern)
class="p=[1,2,3,4]&a=aaa&c=f()"
Its purpose: post-processing input Field through class atribute
Any advice to define a good pattern ?
You might want to look into Javascript Object Notation (JSON) at http://www.json.org/.
It describes basically what you are looking for, and is an industry standard way of packaging data nicely, so you won't be alone in using it.
EDIT: Given that the problem requires function references and/or runtime evaluation of functions, and that the whole thing is meant to be wrangled into a double quoted html class attribute, I second Gumbo's answer of just using javascript.
The easiest would be to use plain JavaScript:
attr="p=[1,2,3,4];a='aaa';c=f"
Note that c=f() is not assigning the function f to c but the return value of the function f. c=f is assigning the function f to c.
You can evaluate that code with eval:
eval(element.getAttribute("attr"));
Here is a string formatted as JSON:
var dataString = "'FirstName' : 'David', 'LastName' : 'Robbins', 'Dates' : {'BirthDate' : '12/12/1966', 'Graduated': '6/21/1984'}"
You can de-serialize the string to a Javascript object with the following call:
var userData = eval("(" + dataString +")");
You could natrually wrap the eval in another function.