How can I differentiate between $ (jQuery) and $scope from AngularJS? - javascript

In jQuery, we do DOM Manipulation like,
$(this).hide();
whereas in AngularJS , we have the scope of the controller using which we can do a lot.
$(scope).somevar=somevalue;
Can we compare these two different Javascript Objects?

$(scope) is not proper angular syntax AFAIK. The dollar sign $ in JS is not a special character. it can be part of a variable like a lot of other symbols.
There is no conflict natively between jQuery's $ and angular's $scope, $resource, $q etc. They're different variables, just like j, jscope, jresource, jq would be different variables.
As for comparing these values, you're in a severe case of apples to oranges. jQuery-wrapped DOM elements may be comparable to arbitrary values in your scope but you'd have to determine some meaningful way to perform that comparison.

Related

Difference between event and $event [duplicate]

Does anyone know if the reasoning behind the use of dollar methods and variables in angularJS is to instruct angularJS to avoid checking those values when a digestion is going on? So, if angular comes across $scope.$value and $scope.value, then it will avoid checking the former since it's prefixed with a dollar character in its variable name?
It is just a naming convention from the below snippet
http://docs.angularjs.org/tutorial/step_05
'$' Prefix Naming Convention
You can create your own services, and in
fact we will do exactly that in step 11. As a naming convention,
angular's built-in services, Scope methods and a few other angular
APIs have a '$' prefix in front of the name. Don't use a '$' prefix
when naming your services and models, in order to avoid any possible
naming collisions.
http://docs.angularjs.org/guide/concepts#angular_namespace
Angular Namespace
To prevent accidental name collision, Angular
prefixes names of objects which could potentially collide with $.
Please do not use the $ prefix in your code as it may accidentally
collide with Angular code.
There are a few times Angular ignores variables prefixed with the dollar sign:
In Schumli's comment below, where json filters will not output them
When using the {{ }} directive, angular will not show nested $
variables. For example this only displays the visible property.
<div ng-init="n = { visible: 'foo', $ignore: 'bar' };">{{ n }}</div>
Additionally when adding an explicit watcher on a scope object, changes to properties with a leading dollar sign of this object will not trigger the watcher. See this updated fiddle.
angular.equals() ignores keys prefixed with $.
The $ prefix denotes a variable, parameter, property, or method that belongs to the core of Angular.
Properties on objects that originate inside the framework, but are not actually part of the API, may begin with $ – or even $$ – to denote a private method or property. This is the same way the _ prefix is often used in other libraries.
It doesn't have any effect on the way code is interpreted by the runtime, although the framework itself may give it special meaning. Basically, it is a naming convention that says "You shouldn't mess with this".
Not completely sure, but I believe AngularJS internals rely on manipulating these $-prefixed variables during the digest. Checking these variables would mean that the digest would never stabilize, since they may constantly change during each cycle of the digest.
Don't quote me on it though. :)
Dollar ($) signs also prevent elements from being iterated (or interpreted) in certain directives.
So for example properties that start with $ are not used in ng-repeat because of an if clause in the for loop:
if(collection.hasOwnProperty(key) && key.charAt(0) != '$')
Someone made an issue about the topic here on angulars github page
In the method shallowCopy properties that start with $$ are skipped because of an if clause while iterating the properies:
if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
I always figured $ looks like an "S" for service.
#MarcoS provided the link to https://thinkster.io/a-better-way-to-learn-angularjs/scope-vs-scope which explains a difference between $scope and scope. I found this useful, adding to the information in other answers.
In an angular directive there is a link and controller. The link is a standard function with a fixed set of parameters: scope, element, attributes object.
The controller's arguments are managed by the Angular injector and are not order dependent. The injector resolves which objects to pass in by looking for the parameters starting with $.
The author of https://thinkster.io/a-better-way-to-learn-angularjs/scope-vs-scope does a better job of explaining it.
There's a huge difference, not in variables, but in the parameters that a controller receives. A scope parameter is completely different from a $scope one.
For more information, check out this useful post: http://www.thinkster.io/angularjs/aw9kWmdnik/angularjs-scope-vs-scope

$ sign in JavaScript function

I've found some weird for me function in the project that I'm currently working on:
Building.Widget.ClientIdV2 = function Building$Widget$ClientIdV2() {
...
What does $ mean here and what does the "name" of this function mean (Building$Widget$ClientIdV2) ? I've seen also ... = function () { code so far..
Thank you.
The dollar sign has no special significance. It is just a character you can use in an identifier.
The name of the function can be used to refer to the function from inside its own scope (which can be useful for recursive functions) and will appear in useful places like stack traces.
$ is just another character you can use in an identifier, it has no intrinsic special meaning. It could be Q or _ just as easily.
In that particular example, the original author is naming the function in a way that they can readily see that it's the ClientIdV2 function on the Widget object on the Building object. But that's just the author's convention. That's useful for looking at call stacks and such.
It looks like it's someones naming convention. You can preety much put anything that you want in Javascript variable names. You should try finding general naming conventions in Javascript in case that you're interested in that(it will make your work with other developers much easier).
For example, some people like to put the $ before jQuery variables, implying that they can chain functions on that selection.
In Javascript it's completely valid to use $ in names, just like letters or underscores, so syntactically it means nothing special. Thought it's frequently used to give extra semantic meaning to names, for eg. it may indicate that a variable is special to a system (internal variable, global, etc.). In your case I believe $ indicates object hierarchy. The use of $ is just conventional.

How to prevent Angular directive normalization?

I'm new to Angular so trying to get to grips with it. One early gripe is that the directive is hyphen-ated when used as an html element, and camelCased in the Javascript definition.
For example this Javascript:
myApp.directive('myDirective', function() {
...etc
Correlates to this html:
<my-directive></my-directive>
I really dislike the fact that the same directive is formatted completely differently. Searching for use of it across my codebase now involves 2 searches.
Ironically I'd like to normalize these two formats. Is there a way of configuring my setup so that the html and the Javascript definition both use the same case?
Angular is opinionated about many things, including this one. This behaviour is hardcoded, and normalization cannot be overriden.
Angular has its reasons to force directive names to be camel-cased, because camel case is used as the convention for naming services, and myDirective directive becomes myDirectiveDirective service internally.
Apparently, :-_ characters are used as delimiters for normalizing to camel case. While none of them are valid in HTML element name, - is the only future-proof delimiter for custom elements among them.
While being convention-breaking, validator-outraging and potentially invalid, any other delimiters can be used, as long as browsers are ok with them. E.g. dot symbol has good chances to do the trick
<my.directive></my.directive>
in modern browsers.
Breaking Angular's conventions right from the start isn't the best way to make friends with it, the best thing the one could do is to deal with it and to search for my-?directive regexp instead, as long as development tools got the support for searching regexps.
Unfortunately you can't. It's done this way because the DOM is not case sensitive.
But you should quickly get used to it.
Regards,
Eric

Symbol.for(string) in ECMAScript 6

It took me a while but I finally figured out what the purpose of symbols in ECMAScript 6 is: avoiding name collision when attaching properties to shared objects - HTML elements e.g. (In case you're stuck on the same question, I recommend this article.)
But then I stumbled upon Symbol.for(). Apparently ECMAScript 6 will maintain a global symbol registry which you can query with this function by providing the symbol description. Come again? If I use symbols to avoid name collisions, why would I want code other than my own to use them? (*) And how would I avoid name collisions in that global registry? Sharing of symbols seems to completely subvert the concept and a global registry doubly so.
(*) Yes, I know symbols aren't truly private, but that's besides the point.
If you don't want your symbols to be available in GlobalSymbolRegistry, just don't use Symbol.for.
Only use it if you want to allow other codes to use your symbol.
In the following example, I create a symbol to store data in DOM elements. And I may want every other code (e.g. internal raw uncompiled handlers) to read that data. So I make the symbol globally available.
var sym = Symbol.for('storeDataInDOM');
document.querySelector('button')[sym] = 'Hello, world!';
<button onclick="alert(this[Symbol.for('storeDataInDOM')])">Click me</button>
It's like creating global variables: should be avoided in general, but has its advantages. But with symbols instead of strings.
If I use symbols to avoid name collisions, why would I want code other than my own to use them?
That's not the only use case of symbols. The two most important other ones are:
they don't collide with string-keyed properties
they are not enumerated by the usual mechanics
Sharing of symbols seems to completely subvert the concept and a global registry doubly so.
Not necessarily. Right from that article you read: "The registry is useful when multiple web pages, or multiple modules within the same web page, need to share a symbol." The best example for these are the intrinsic symbols - they guarantee interoperability across realms, that's why the global symbol registry is more global than your global scope.
For example you might have a library that is loaded in a web page, an iframe and a web worker. If you share data between those environments (realms), all of the three instances of your library would want to use the same symbol.
There also is a real need interoperability between different libraries, which might not even know about each other. Good examples are transducers, algebraic structures or promises. Would ES6 already be in use, all of these would have agreed on common names in the global symbol registry, instead of relying on strings like these or the then method.
Another good example would be custom hooks defined by your engine, e.g. a Symbol.inspect = Symbol.for("inspect") that you can use to define custom stringification behavior to be used by console.log. Admittedly, that symbol does not necessarily need to be made available through the global symbol registry, it could as well be put on that specific library object (e.g. console.inspect = Symbole("console.inspect")).
And how would I avoid name collisions in that global registry?
Just like you previously did with properties, or global module objects: by using very long, very descriptive names - or by good faith. Also there are some naming conventions.
I invented the most useful feature of Symbol.for() call. If there is using symbols in your code sometimes it is difficult to use conditional breakpoints while debugging. For example, you need to catch if the variable equals the value which is of symbol type and this value binded in the different module. The first difficult way is to use this value as a constant and export it from that module. In this case, the condition of the breakpoint will look:
catchedVariable === exportedSymbolConst
But the easiest way is to temporarily change the code inside the module adding .for to Symbol. Then you can write the condition:
catchedVariable === Symbol.for('string_key')
After the successful debugging you will be changing the code back just removing .for part.

ng-init vs function in controller, which is better practice when using $parent?

I have a Bootstrap modal which corresponds to a ng-repeat list. I would like to access the ng-repeat scope data from its parent, which contains the modal. I do this so that when the modal button is clicked on the list, the corresponding data from the JSON appears in the modal.
I have found 2 ways of doing this, and I wonder which is the best alternative?
Method 1
View:
<li ng-init="myFunction(item,$parent)" ng-repeat="item in data.webapps_1.items>
Controller:
$scope.myFunction = function(item,parent){
parent.selected=item.counter-1;
};
Method 2 View:
<li ng-init="$parent.selected=item.counter-1" ng-repeat="item in data.webapps_1.items>
With nothing in the controller.
I have read in the Angular ngInit docs that
The only appropriate use of ngInit is for aliasing special properties
of ngRepeat, as seen in the demo below. Besides this case, you should
use controllers rather than ngInit to initialize values on a scope.
But the list of special properties of ngRepeat does not include $parent.
So, which is the better practice? Including the expression $parent.selected=item.counter-1in the controller or in ngInit directive?
Thanks in advance
Either of the two fine really, so long as you're consistent. Depends on the scale of the app though.
IMO if the app is going to be large you'll want to go the function way, to better adhere to the whole MVC philosophy of decoupling and separation of concerns (http://victorblog.com/2013/03/18/angularjs-separation-of-concerns/).
ng-init="myFunction(item,$parent)"
It's a better structure because you want to keep most of your business logic in the javascript controllers, not in the view.
Personally, I prefer the ng-init approach. Mainly for consistency of the timing of the call (i.e. more like an "onLoad" event). I understand the concerns regarding SoC and that makes sense as well. However, I have seen some specific scenarios (particularly pages with a lot of directives), when changing scope variables with the = binding in the (non ng-init) function, caused extra (premature) digest loops. Obviously it depends on what you're actually doing in the function as well as your scope bindings, but in my opinion its best to just avoid the situation and use the ng-init directive across the board. Your experience may obviously vary wildly. Like others said just pick an approach and stick with it and be aware of the impact of every call that you're making in the function itself. :)
EDIT: Regarding the accepted answer, the example was used passing values to the init function in ng-init. And hes correct that is a violation of the pattern. I typically use parameterless init functions and call it like:
ng-init="model.init()"
Any reference to $scope or what have you would happen inside the function itself. I rarely pass anything to init, unless its a static value. For example in several cases on an ASP.NET WebApi project, I wanted minimize round trips to the server so I would resolve a value from the MVC View Model, which is just rendered and passed as a string like so:
ng-init="model.init(#model.myValue)"
In those cases its usually best to keep it to simple value types (i.e. string, int, etc), but I have occasionally for small directives such as one that does nothing but display a dropdown, I have passed arrays to pre-populate the dropdown binding. Those cases are extremely situational and this one in particular would obviously only work when using server side rendering of the template.

Categories

Resources