Angularjs attribute literal value vs. expression evaluation - html

I'm having some trouble to understand how angularjs decides how to evaluate attributes. For exemple, using ng-repeat:
<div ng-repeat="item in items"></div>
the item in items part will be evaluated as an expression, looking for the content of items array set somewhere in the controller.
But using ng-src:
<img ng-src="/path/to/img/"></img>
the path/to/img/ will be considered a literal. If I want to make it 'dynamic' I must write:
<img ng-src="/path/to/img/{{id}}"></img>
where id is set in the controller.
Question: how do I choose which behaviour to follow when defining custom attributes for my custom directive?

There's nothing to choose from. Expressions in attribute values are interpolated by $interpolate service. And the latter uses $parse service to evaluate each expression in string.
Some directives (ng-if, ng-hide) expect nothing but expression in attribute, which is usually designated in API documentation. In this case the brackets can be omitted, and the expression will be evaluated within directive - $scope.$watch is being used often instead of calling $interpolate explicitly.
ng-repeat attribute syntax (it is referred as 'repeat expression' in documentation) is parsed by the directive itself and isn't related to Angular expressions.

Defining your attributes as expressions will give you huge possibility in directives chain - you will escape isolate scope error that made us all straggle. A specially chains with ng-repeat or another default ones.
What I saw in bootstrap code and started to use - I $eval expressions within own scope then passed to directives local variables instead of defining in isolate scope.
<div custom some-val='ctrl.data'></div>
//directive link or controller
var private = $scope.$eval($attrs.someVar);
Only con for $eval is that it's good for static variables. For dynamic you need either already evaluated value or best way is to put it into ng-model that can be shared between directives (fix me if I'm wrong)
Or just run watcher on result of expression that is much simpler.

Related

ES6 default parameter not defined in arguments

Default parameters aren't assigned to the arguments Array like Object :
function fn(test = "test") {
console.log(arguments); //[]
}
This might be usefull to know only what the user passes to the function, but it seems tricky too.
Will this change?
No, this will not change.
In fact it already did change - previously every index on the arguments object was mapped to the respective parameter variable for reading and writing (a horror to reason about!). This proved to have devastating performance implications as it prevented a lot of engine optimisations, and was deprecated in ES5 (however, for compatibility reasons, only in the new strict mode). In ES6, the behavior is also deprecated in sloppy mode functions if they use new ES6 features in their parameter list (like destructuring, default initialisers or rest syntax).
The arguments object is just a simple object with the argument values that were passed to the function. Notice that defaults are not passed, it's just syntactic sugar for initialising variables in the begin of the function body.
If mapped to scope variables, it's much more complicated.

Fluent bind not working as expected

Suppose I am binding using
bs.Bind(y)
.For(v => v.Visibility)
.To("Failures['TaxPercent'].Length")
.WithConversion("Visibility")
.WithFallback(false);
Where Failures is a dictionary which would contain the property name (e.g. TaxPercent) if, and only if, the property fails validation.
Therefore Failure['TaxPercent'] returns the validation failure message (e.g value missing).
I want to have an expandable textview in Android which is visible only when the error is detected. I used the above code and it is not working. The fallback value does not trigger when Failure['TaxPercent'] does not exist in the dictionary.
How do I get an expandable/collapsible textview based on the validation result using a dictionary in the viewmodel??? I would really like to use a dictionary because that would save me from creating IsErrorVisible for each property.
Oddly enough, using a dictionary works for retrieving the error message though, but not for visibility! In other words, this is working great
bs.Bind(y)
.For(v => v.Text)
.To("Failures['TaxPercent']");
Also, any reason why I cannot concatenate the binding, meaning can I do this???
bs.Bind(y)
.For(v => v.Text)
.To("Failures['TaxPercent']")
.For(v => v.Visibility)
.To("Failures['TaxPercent'].Length")
.WithConversion("Visibility")
.WithFallback(false);
EDIT
The error msg in the log is
MvxBind:Error:168.86 Problem seen during binding execution for binding Visibility for Failures['TaxPercent'].Length - problem ArgumentException: The value passed in must be an enum base or an underlying type for an enum, such as an Int32.
If the dictionary doesn't contain an entry for 'TaxPercent' then the expression Failures['TaxPercent'].Length will not evaluate (an exception will be throw) so UnsetValue will be used.
In the case of UnsetValue, the ValueConverter will not be called, and the Fallback will be used. This is the same pattern as in Wpf - http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty.unsetvalue(v=vs.110).aspx
For your particular situation, it looks like you could either:
change the Fallback to the correct value for the platform instead of to a boolean value (the question didn't specify which platform(s) you are using)
create a new Visibility ValueConverter that takes Failures as its binding source and 'TaxPercent' as its parameter
remove the .Length from your binding expression - just test on the existence of the entry.
you could switch to free text binding expressions - then you could do more complicated binding statements, including nested bindings, multiple value converters, multiple fallback values, ...
For this particular case, I would just drop the .Length
For "any reason why I cannot concatenate", that won't work as the return type of Bind is a single Fluent binding entry - not a Fluent binding set.

What is the use of ..._ as the parameter list in an ActionScript 3.0 function?

I'm working on a project that's integrating with StrobeMediaPlayback and have been having trouble working out why I can't get my media loaded.
One of the two available public functions for the class is:
public function loadMedia(..._):void
If this is a rest parameter, there's no use of '_' as an argument list within the function.
What's going on here? The class extends Sprite, so its not a case of an override.
It is the ... (rest) parameter.
The parameter does not need to be called rest; it can have any name that is not a keyword.
Valid variable names start with a non number character and can include alphanumeric characters, the underscore and the dollar sign. So _ is a valid name for a parameter.
The question why exactly the parameter was named that way can probably only be answered by the author of that function. So here's what I think: Aside from its use as a short variable name for often used objects (like $ as shorter name for jQuery in javascript), the name _ is sometimes used as a placeholder, or unused variable. If I understand the question right, an the variable isn't even used in the function, it probably was added for future use. This way the API wouldn't need to be changed once the feature based on this parameter will be implemented. The developers maybe thought that a parameter name with semantic meaning could confuse the users, as they would expect it to actually doing something.

How to set the value of a variable in a udf requiring a path-call

I'm trying to use a user-defined function in XSLT that repeatedly calls the value of a certain string. That string is based on the outcome of an XPath expression that doesn't change within the span of a single function call. I thought it would be a good idea to assign it to a variable rather than look it up over and over again.
Unfortunately, at least in Saxon's implementation, you cannot use an XPath expression requiring a node inside a function, even one based on an absolute path, without first using a throw-away line to let the function know you are discussing the root document rather than some other one.
So, for example, the following code throws an error:
<xsl:function name="udf:LeafMatch">
<xsl:param name="sID"></xsl:param>
<xsl:variable name="myLeaf" select="/potato/stem[#sessionID=$sID][scc]/scc/#leafnumber"/>
Normally, the solution is just to first call any global variable to give context. For example, the following works inside of an udf ($root is a variable identified with the root node):
<xsl:for-each select="$root">
<xsl:value-of select="/potato/stem[#sessionID=$sID][scc]/scc/#leafnumber"/>
</xsl:for-each>
But this doesn't work when trying to use Xpath to fix the value of a variable because I'm not allowed to put the expression within a for-each.
I also tried using
<xsl:choose><xsl:when select"$root"><xsl:value-of select="/potato/stem[#sessionID=$sID][scc]/scc/#leafnumber"/></xsl:when></xsl:choose>
to give it context, going on what I saw here:http://www.stylusstudio.com/xsllist/200504/post00240.html
That didn't work either.
FWIW, passing the variable into the function is problematic because the Xpath expression used to define "myleaf" depends on the context node, and I don't know how to get Xpath to call one path based on values in the current context node.
For example, in the code calling this function I have something like:
<xsl:for-each select="/potato/stem[eye]">
<leaf = "{udf:LeafMatch(#sessionID)}"/>
</xsl:for-each>
I'm working in the context of a /potato/stem[eye] node and using the udf to look for a /potato/stem[scc] node that has the same value of #sessionID. I don't know how to reference the value of #sessionID from the current context node in the predicate of an XPath searching for other nodes in a completely different part of the XML tree, so I was using a udf to do that. It was working fine until I decided to try to use a variable for the string rather than having the processor look it up each time.
I was trying to avoid going one level deeper (having my function itself call a named template or putting a named template inside my original for-each and having that named template call a function).
So my questions are:
A. For a user-defined function, how do I set a variable that depends on an XPath expression?
B. Is there a snazzy way in Xpath to use values drawn from the current content node in the predicates of the Xpath expression you are trying to test?
So my questions are:
A. For a user-defined function, how do I set a variable that depends
on an XPath expression?
B. Is there a snazzy way in Xpath to use values drawn from the current
content node in the predicates of the Xpath expression you are trying
to test?
Both questions are quite unclear.
A: I assume you actually mean:
"Inside an xsl:function how do I define a variable that depend on
the context node?"
The answer: You can't. By definition there is no context node within an xsl:function. This is defined by the W3C XSLT 2.0 specification in the following way:
"Within the body of a stylesheet function, the focus is initially
undefined; this means that any attempt to reference the context item,
context position, or context size is a non-recoverable dynamic error.
[XPDY0002]"
You can, however, pass as a parameter the intended context node (or just the document node that must be used as current). Or, alternatively, you may refer to a globally defined variable.
B: This question is completely not understandable:
What is "snazzy"?
What is "current content node"? Please, provide an example of a specific task to be accomplished in the wanted "snazzy" way.

Bang Notation and Dot Notation in VBA and MS-Access

While perusing an application that I'm documenting, I've run across some examples of bang notation in accessing object properties/methods, etc. and in other places they use dot notation for what seems like the same purpose.
Is there a difference or preference to using one or the other? Some simple googling only reveals limited information on the subject with some people actually using it in opposite cases. Perhaps there is a coding standards section from MS somewhere that indicates the method of madness?
Despite the (formerly) accepted answer to this question, the bang is not in fact a member or collection access operator. It does one simple and specific thing: The bang operator provides late-bound access to the default member of an object, by passing the literal name following the bang operator as a string argument to that default member.
That's it. The object doesn't have to be a collection. It doesn't have to have a method or property called Item. All it needs is a Property Get or Function which can accept a string as the first argument.
For much more detail and proof, see my blog post discussing this: The Bang! (Exclamation Operator) in VBA
The bang operator (!) is shorthand for accessing members of a Collection or other enumerable object, such as the Fields property of an ADODB.Recordset.
For example, you can create a Collection and add a few keyed items to it:
Dim coll As Collection
Set coll = New Collection
coll.Add "First Item", "Item1"
coll.Add "Second Item", "Item2"
coll.Add "Third Item", "Item3"
You can access an item in this collection by its key in three ways:
coll.Item("Item2")
This is the most explicit form.
coll("Item2")
This works because Item is the default method of the Collection class, so you can omit it.
coll!Item2
This is short-hand for both of the above forms. At run-time, VB6 takes the text after the bang and passes it as a parameter to the Item method.
People seem to make this more complicated than it should be, which is why it's hard to find a straightforward explanation. Usually the complications or "reasons not to use the bang operator" stem from a misunderstanding of how simple it actually is. When someone has a problem with the bang operator, they tend to blame it instead of the real cause of the problem they are having, which is often more subtle.
For example, some people recommend not using the bang operator to access controls on a form. Thus, Me.txtPhone is preferred over Me!txtPhone. The "reason" this is seen as bad is that Me.txtPhone will be checked at compile-time for correctness, but Me!txtPhone won't.
In the first case, if you mistype the code as Me.txtFone and there is no control with that name, your code won't compile. In the second case, if you wrote Me!txtFone, you won't get a compile error. Instead, your code will blow up with a run-time error if it reaches the line of code that used Me!txtFone.
The problem with the argument against the bang operator is that this problem has nothing to do with the bang operator itself. It's behaving exactly the way it's supposed to.
When you add a control to a form, VB automatically adds a property to your form with the same name as the control you added. This property is part of the form's class, so the compiler can check for typos at compile-time if you access controls using the dot (".") operator (and you can access them using the dot operator precisely because VB created a named control property for you).
Since Me!ControlName is actually short-hand for Me.Controls("ControlName")1, it should not be suprising that you don't get any compile-time checks against mistyping the control name.
Put another way, if the bang operator is "bad" and the dot operator is "good", then you might think
Me.Controls("ControlName")
is better than
Me!ControlName
because the first version uses a dot, but in this case, the dot isn't any better at all, since you are still accessing the control name via a parameter. It's only "better" when there is an alternative way to write the code such that you will get compile-time checking. This happens to be the case with controls due to VB creating properties for each control for you, and this is why Me.ControlName is sometimes recommended over Me!ControlName.
I had originally stated that the Controls property was the default property of the Form class, but David pointed out in the comments that Controls isn't the default property of Form. The actual default property returns a collection that includes the contents of Me.Controls, which is why the bang short-hand still works.
Couple gotchas to serve as addenda to the two exceptional answers already posted:
Accessing recordset fields in forms vs. reports
The default item of Form objects in Access is a union of the form's Controls collection and the form recordset's Fields collection. If the name of a control conflicts with the name of a field, I'm not sure which object is actually returned. Since the default property of both a field and a control is their .Value, it's often a "distinction without a difference." In other words, one normally doesn't care which it is because the values of the field and control are often the same.
Beware of naming conflicts!
This situation is exacerbated by Access's Form and Report designer defaulting to naming bound controls the same as the recordset field to which they are bound. I've personally adopted the convention of renaming controls with their control type prefix (e.g., tbLastName for the text box bound to the LastName field).
Report recordset fields aren't there!
I said earlier the Form object's default item is a collection of Controls and Fields. However, the Report object's default item is only its collection of Controls. So if one wants to refer to a recordset field using the bang operator, one needs to include that field as the source for a (hidden, if desired) bound control.
Beware conflicts with explicit form/report properties
When one adds controls to a form or report, Access automatically creates properties that refer to these controls. For example, a control named tbLastName would be available from a form's code module by referring to Me.tbLastName. However, Access will not create such a property if it conflicts with an existing form or report property. For example, assume one adds a control named Pages. Referring to Me.Pages in the form's code module will return the form's Pages property, not the control named "Pages".
In this example, one could access the "Pages" control explicitly using Me.Controls("Pages") or implicitly using the bang operator, Me!Pages. Be aware, though, that using the bang operator means that Access might instead return a field named "Pages" if one exists in the form's recordset.
What about .Value?
Though not explicitly mentioned in the question, this topic came up in the above comments. The default property for Field objects and most "data-bindable"¹ Control objects is .Value. Since this is the default property, VBA will implicitly return the .Value property's value when it does not make sense to return the object itself. Thus, it's common practice to do this...
Dim EmployeeLastName As String
EmployeeLastName = Me.tbLastName
...instead of this...
EmployeeLastName = Me.tbLastName.Value
The above two statements produce identical results because EmployeeLastName is a string.
Beware the subtle .Value bug when keying dictionaries
There are some cases where this convention can cause subtle bugs. The most notable--and, if memory serves, only--one I've actually run into in practice is when using the value of a Field/Control as a Dictionary key.
Set EmployeePhoneNums = CreateObject("Scripting.Dictionary")
Me.tbLastName.Value = "Jones"
EmployeePhoneNums.Add Key:=Me.tbLastName, Item:="555-1234"
Me.tbLastName.Value = "Smith"
EmployeePhoneNums.Add Key:=Me.tbLastName, Item:="555-6789"
One would likely expect that the above code creates two entries in the EmployeePhoneNums dictionary. Instead, it throws an error on the last line because we are trying to add a duplicate key. That is, the tbLastName Control object itself is the key, not the value of the control. In this context, the control's value does not even matter.
In fact, I expect that the object's memory address (ObjPtr(Me.tbLastName)) is likely what's being used behind the scenes to index the dictionary. I did a quick test that seems to bear this out.
'Standard module:
Public testDict As New Scripting.Dictionary
Sub QuickTest()
Dim key As Variant
For Each key In testDict.Keys
Debug.Print ObjPtr(key), testDict.Item(key)
Next key
End Sub
'Form module:
Private Sub Form_Current()
testDict(Me.tbLastName) = Me.tbLastName.Value
Debug.Print ObjPtr(Me.tbLastName); "..."; Me.tbLastName
End Sub
When running the above code, exactly one dictionary item is added each time the form is closed and re-opened. Moving from record to record (and thus causing multiple calls to the Form_Current routine) does not add new dictionary items, because it is the Control object itself indexing the dictionary, and not the Control's value.
My personal recommendations/coding conventions
Over the years, I've adopted the following practices, YMMV:
Prefix Form/Report control names with control type indicators (e.g., tbTextBox, lblLabel, etc.)
Refer to Form/Report controls in code using Me. notation (e.g., Me.tbLastName)
Avoid creating table/query fields with problematic names in the first place
Use Me! notation when there are conflicts, such as with legacy applications (e.g., Me!Pages)
Include hidden report controls to gain access to report Recordset field values
Explicitly include .Value only when the situation warrants the added verbosity (e.g., Dictionary keys)
¹ What's a "data-bindable" control?
Basically, a control with a ControlSource property, such as a TextBox or ComboBox. A non-bindable control would be something like a Label or CommandButton. The default property of both a TextBox and ComboBox is .Value; Labels and CommandButtons have no default property.