I am confused by "scope" in the Handlebars template engine. In its documentation on block helpers, I read
"Private variables provided via the data option are available in all
descendent scopes. Private variables defined in parent scopes may be
accessed via pathed queries."
I understand the meaning of scope as used in programming languages (where {} are often used to create scopes). But what does "scope" refer to in Handlebars templating?
It is actually quite similar, see an example here: https://jsfiddle.net/veraee/63gs19j3/11/
Just to make it clear, there are two types of "variables" in handlebars:
The model/context. This is the data you inject into the template on redering. Use this for your normal work.
These variables are referenced in the template via its name in {{}}:
{{firstname}}
and are exposed in the javascript of the helpers via "this":
this.firstname
The "#"-variables. This data is generated inside the helpers via javascript.
These variables are referenced in the template via its name with '#'-prefix:
{{#foo}}
and are exposed in the javascript of the helpers via "options.data":
options.data.foo
The citation from the handlebars doc in the OP is about number 2.
In a programming language the "{" enters a scope,
in handlebars a block "{{#myBlock..." enters a scope.
Similar to the programming language you can use all variables from the outer scope in the inner scope (foo, bla),
but if you redefine one in the inner scope (bla), the original value will
be shadowed in the inner scope. When leaving the inner scope and being again
in the outer scope, you get the old value of bla again.
But note these differences to programming languages:
This scoping does not happen by some magic of the programming language syntax,
you have to do in on your own, as the doc also mentions, i.e. this way:
data = Handlebars.createFrame(options.data);
As a bonus, you can reach the shadowed variables (which is usually not possible in programming languages)
by prefixing the name with "../" which means: look at the previous (aka. outer) scope (see the "{{#../bla}}" in the inner scope in the example).
Related
I have a schema that has many complexType, some of which have subtypes (via xsi:type). I need to create an XQuery expression that checks that an element (MyPath) is a member of a parent type, but no others, I've tried an expression in the form below with no luck.
/MyPath[element(*,ParentClass) and not element(*,ChildClass)]
It appears element applies to all the children in the context it is called, but not itself (MyPath), which yields no results.
I also tried the instance of operator, but this appears to only work for simpleType.
You should use
. instance of element(*, ParentClass)
and not(. instance of element(*, ChildClass))
If this doesn't work please supply an MCVE
An alternative, using Saxon extension functions, is to test the type annotation directly: saxon:type-annotation(.) eq xs:QName('ParentClass')
Of course, there's a question about whether this is good practice. The whole point of defining a derived type is that it is supposed to be substitutable for the base type; everywhere you can use an instance of the parent type, you should be able to substitute an instance of the child type. You appear to be deliberately trying to contrive a query in which this is not the case.
For all XQuery queries I execute, I define a default element namespace, like so:
declare default element namespace 'http://example.com';
(: rest of the query :)
But to hardcode this namespace is kind of cumbersome. Can I dynamically define a default namespace, from an external variable?
It tried:
declare default element namespace $namespace;
(: error: Expecting quote, found '$'. :)
.. and:
declare variable $namespace external;
declare default element namespace $namespace;
(: error: Default declarations must be declared first. :)
... but they don't work, unfortunately.
I'm currently using BaseX 7.7.2, by the way.
Unfortunately, it is only possible to statically declare default namespaces, as the grammar only allows for a URILiteral in this place. The default element namespace is in the static context of the query.
However, you can build QNames out of a variable containing the namespace dynamically (from a variable). You can build new elements with such QNames with computed element constructors. The XPath navigation, however, would be more involved, because you will have to filter namespaces explicitly.
It's generally assumed that if you know the local names of the elements in the source document statically, then you will also know their namespaces statically. This assumption is not always correct; you sometimes encounter a family of namespaces (e.g. different versions of a namespace) that use the same local names; but XQuery (and XSLT) aren't well designed to handle this scenario.
So if you know the names of the elements statically, and use path expressions like invoice/customer/address, then the names in this path are simply a shorthand for the full expanded names, and it's assumed that the shorthand can be resolved by the compiler. That's why the namespace declarations are all fixed statically.
If you don't know the names of the elements you are querying statically, then you're probably writing a query that uses wildcards (e.g. child::*) rather than explicit local names like "invoice". In that case the default namespace declaration never comes into play anyway.
So the only situation I can see where you have trouble is the scenario above where multiple namespaces use similar sets of local names. Most people advise against using namespaces that way, for that very reason, but unfortunately not everyone has followed this advice.
I have to work with Dynamics 2012 r3 and x++ and I wonder:
what is "::" - its inherit, implementation or what?
why some variables are write like "_vensGroup" - that _ means something or this is just convention?
:: is a scope. It allows you to use class method (on tables and classes). The point is used to call an object method.
The scope is also used to call values on BaseEnum.
_ is a prefix for parameters. It's a convention. It allows you to recognize local variable and parameters. As parameters are not ment to be changed in a method (they are passed by value), you will always be able to distinguish it from local variables and use them in your code.
To answer both questions:
:: is a scope dereference to a (static) method (as opposed to . which dereferences a variable, constant or property), usually for the Global scope, but it could be for other similar scopes. It is reserved.
The underscore prefix is just a naming convention. It is not part of the language.
Regarding your underscore question:
A widely spread convention is to use leading underscores to indicate passed parameters e.g.
public void foobar(int _myInt, str _myStr)
{
...
}
See here for the best practice MSDN page describing this convention.
In addition to the other answers to your question, :: is used not only to call to static table/class methods, but for other purposes as well, e.g. call methods in maps or reference enums.
Let's say you have a partial of some sort, which uses a global variable:
<img src="{{assets}}/logo.png">
Once you include the partial with specific data, either {{parseJSON}} or external JSON data:
{{#parseJSON '{"demo": true}'}}
{{>navigation}}
{{/parseJSON}}
all global variables like {{assets}} "killed" or at least overridden. Is there any chance to have still access?
Thanks in advance!
this is a known "issue" with Handlebar's partials in that the context inside a partial only includes the passed in context and no parent context, etc.. you can read more about the issue here.
fortunately the Assemble team provides a {{partial}} helper that will allow access to a more "expected" context, including global properties. once this helper is installed, you use it in a slightly different way than a normal partial:
{{#parseJSON '{"demo": true}'}}
{{partial "navigation"}}
{{/parseJSON}}
note that the partial helper is invoked with the name of the partial to include as a string.
that all being said, a new version of Handlebars was just released (v2.0.0-alpha.1) that may provide support for this natively. check out the more recent posts of issue thread i linked to above.
hope this helps.
As a workaround, the other way to cope with this is to pass the parent context explicitly to the partial:
{{#..}}
{{>partial}}
{{/..}}
Yeah.
You can access the current template's instance by doing Template.instance(). But you often run into situations where you have to access other templates' instances as well. For example, if you use ReactiveVar, then you would want to get or set variables that are attached to other template instances.
I came across How to get the parent template instance (of the current template) but this is not complete.
Q1. How can we access any template's instance, not just the current template's
Q2. Is it against the Meteor way if I need to access other templates' instances?
you can try to set your template variable directly at the template level instead of inside the instance.
Template.example.myVariable = new ReactiveVar();
instead of
Template.example.onCreated(function (){
this.myVariable = new ReactiveVar();
});
The closest I got was to target the template by one of its elements (assume the template contains a form)
Blaze.getView($('form')[0]).templateInstance().someReactiveVar.set('changed')
If your target templates are in the same file, you can just define the reactive variable outside the template functions, at the beginning of the file. All templates in the file will access it.
If your target template is the parent template, (or any further parent template) you can access its data context using Template.parentData() the argument being the rank of the parent (default is 1). It seems that you know that already.
If you need to access a DOM element within a different template in the same page, you can use jQuery selectors.
I don't know any other way to reach another template instance (afaik, there is no Blaze.getTemplate(name) function.) The answer you are referring to seems to be the better you can get.
I think this is purely subjective, since in Meteor there are so many different ways of doing things, but I actually think Session is perfectly suited for sharing variables across several templates. People argue that Session is bad since it's global and can pollute the namespace. I would argue that it's up to the developer to keep their environment clean in any way that works for them. So for instance, this is bad:
Session.set('count', 23);
Session.set('last', new Date());
But this is better:
Session.set('notifications/count', 23);
Session.set('notificatinos/last', new Date());