enter code here :<md-datepicker ng-model="xyz" md-placeholder="trail date"></md-datepicker>
I only wrote this much code but it is showing current date. I didn't provide it any value through ng-model still it is showing current date. Initially, I do not want any value.
Because you have not provided any code, I am unable to check and see what you are doing. Perhaps using ng-init would allow you to set an initial value of nothing?
As per the docs though, its important not to over abuse ng-init and instead apply values in your controller instead.
This directive can be abused to add unnecessary amounts of logic into your templates. There are only a few appropriate uses of ngInit, such as for aliasing special properties of ngRepeat, and for injecting data via server side scripting. Besides these few cases, you should use controllers rather than ngInit to initialize values on a scope.
But at-least ng-init will allow you to do a quick test.
Related
I have an ng-repeat loop that goes over a json array. The array is fetched via $http. Within that loop I want to add some variables to the json object that comes in handy when comparing old/changes values.
<li class="machine" ng-repeat="machine in machines>
....
<input id="machine-host" ng-model="machine.host"
ng-init="machine.editHostDisabled=true;machine.originalHost=machine.host"/>
......
</li>
I read on the angularjs documentation that you are not allowed or "should not" use ng-init. But, here it seems strange to not use this this directive. The above code is clean and easy.
Yes I can set it in the controller, but then I need to loop through the json array of the machines and set the values in the loop. Seems too much of a hassle.
This directive can be abused to add unnecessary amounts of logic into your templates. There are only a few appropriate uses of ngInit:
aliasing special properties of ngRepeat, as seen in the demo below.
initializing data during development, or for examples, as seen throughout these docs.
injecting data via server side scripting.
Besides these few cases, you should use Components or Controllers rather than ngInit to initialize values on a scope.
— AngularJS ng-init Directive API Reference - Overview
Of course I understand that an extensive function can give issues here. But this simple line of code...?
Also, I see the current way of working of many examples all over the web.
What is the rule to follow here ? Adding a controller function to ng-init? But that would be the same thing right? Or is the above code fine?
I am learning angular js and have now a question where I couldn't find the right answer yet.
in the template HTML, you can use expressions to show the scope variables or call scope functions. But I see all the time different versions of it.
{{name}} shows the variable and binds it
{{::name}} the same thing but without binding
userdirective="{{::key}}" But what is the difference here?
ng-if="::field.sortable" With ng-if they are not using {{ but with there userdirective they do?
userdirective="{condition:isActive(route.name),mdColors:{color:'primary'}}" And then there is the last one with just one {. Thats when you create an object.right?
Maybe someone can help me to understand all of it.
Thank you very much for your time. Pat
{{name}} as you say is two-way data-binding
{{::name}} one way databinding
userdirective="{{::key}}" is the interesting case. This statement uses one-way binding into the userdirective ... which means after the $digest it just says userdirective="someValue"
So the userdirective gets that value as a plain value. Now I would have to test it but in the scopepart of the directiive it should say # so it gets read as a string and not as a expression.
The last one is simply as any JSON you build
{ name: value?true:false }
setting value according to conditions that angular evaluates, with a bit of magic involved :D
hope that helps
{{ anything here}} - That is angular expression interpolation. Angular interpolation - here you can find more about that. Basically idea that it interpolate anything you will put inside those brackets. So if you will put expression with some calculations or just variables related to current scope it will convert all variables to their values and apply calculations.
For instance: {{scopevar1 + scopevar2}} in case this variables has some values, let it be 1 and 2, as result we will see 3.
:: - This mean one time binding. For instance {{::scopevar1}} it will be interpolated once and will not check for changes of scopevar1, always stay as first value. Even if scopevar1 will change every second, the value in template will be the same. Angular Expressions - here you can find some live examples and more information.
userdirective="{{::key}}" - This case is nothing more then assigning dynamic value to your directive. UserDirective expectes to get a simple value, but we have it inside our scope, so we need to say: Hey, angular please interpolate scope variable - key, but only once, so my directive will get value, and will not looking for updates of key. And angular does it with pleasure!
userdirective="{condition:isActive(route.name),mdColors:{color:'primary'}}"
The last case is when your directive expects to get some kind of specific JSON. And we don't want to build it inside of controller. It is sometimes easier to do such things in the tempalte. So we put specific object with two properties: condition, mdColors. And saying that first property assigned to result of function, and second one is simple object {color:'primary'}.
That's it!
{{var}} is a two way binding expression and {{::var}} is a one-way binding expression. expression with :: will not change once set, it is a candidate for one-time binding.
go through : https://docs.angularjs.org/guide/expression for better examples on these
{{name}} is the regular case you will find. You basically print the variable name and update it once it changes.
{{::name}} is the same but your value will not receive updates once it stabilises.
So in the first case, your template updates once name is changed. In the latter, it isn't.
userdirective="{{::key}}" is a one-way one-time binding. Leave the :: out and your directive receives updates if key changes. However, if the directive changes key, it will not update the parent.
ng-if="::field.sortable" is a two-way binding. The changes go both ways. In this case, field.sortable is watched by the directive.
userdirective="{condition:isActive(route.name),mdColors:{color:'primary'}}" is used when you want to build adhoc-objects. A popular case is ng-class as well. You may build this object in the controller as well as you should not put too much logic in your template.
In any case, it is advisable to read the excellent docs https://docs.angularjs.org/guide
Let's assume we have an Angular app page with the following line:
<div class="item-name">{{person.FirstName}}</div>
Lower down the user is allowed to change the first name.
<md-input-container class="md-block">
<label>First name</label>
<input ng-model="person.FirstName" type="text">
</md-input-container>
If I put any html or naughty values like <script>console.log(1)</script> the div doesn't show parsed input but the actual string. This seems is good.
Is this safe at all?
Can this be exploited? (e.g. I am aware of operator overloading tricks -- would such a trick work here?)
I cannot seem to find any official or respectable information that says that this is safe, recommended or maybe not recommended.
AngularJS expressions are sandboxed.
Expression Sandboxing
AngularJS's expressions are sandboxed not for security reasons, but instead to maintain a proper separation of application responsibilities. For example, access to window is disallowed because it makes it easy to introduce brittle global state into your application.
However, this sandbox is not intended to stop attackers who can edit the template before it's processed by Angular. It may be possible to run arbitrary JavaScript inside double-curly bindings if an attacker can modify them.
But if an attacker can change arbitrary HTML templates, there's nothing stopping them from doing:
<script>somethingEvil();</script>
It's better to design your application in such a way that users cannot change client-side templates.
For instance:
Do not mix client and server templates
Do not use user input to generate templates dynamically
Do not run user input through $scope.$eval
Consider using CSP (but don't rely only on CSP)
For more information, see AngularJS Developer Guide - Security - Expression Sandboxing
AngularJS Expressions are sandboxed not for security reasons, but the sandboxing does increase security. Angular Expressions are limited to variable and functions that are on $scope. Angular Expressions can't access global functions or global variables.
There is some hint in the official docs: https://docs.angularjs.org/api/ng/directive/ngBind
Typically, you don't use ngBind directly, but instead you use the
double curly markup like {{ expression }} which is similar but less
verbose.
It is preferable to use ngBind instead of {{ expression }} if a
template is momentarily displayed by the browser in its raw state
before Angular compiles it. Since ngBind is an element attribute, it
makes the bindings invisible to the user while the page is loading.
Performance:
The {{}} is much slower.
This ng-bind is a directive and will place a watcher on the passed variable. So the ng-bind will only apply, when the passed value does actually change.
The brackets on the other hand will be dirty checked and refreshed in every $digest, even if it's not necessary.
The double curly brace notation {{ }} to bind expressions to elements is built-in Angular markup.
it is secure to use
you can visit here more information - https://docs.angularjs.org/api/ng/service/$interpolate
A simple example to explain my case:
I have a directive for labels
<input label="{{obj.label}}"/>
But for some other directives I want to use an attribute with name "label"
<other-directive label="My label"></other-directive>
just as an attribute, not processing the label-directive.
I could just rename the attribute to e.g. "my-label":
<other-directive my-label="My label"></other-directive>
but it would be nice to use "label" as an attribute name.
As #ExpertSystem points out in the comments to the question, angular really has no way of knowing out of the box whether your directive should be applied in one case versus another. The only way I can think of to get around this is to include logic in your directive's compile function that knows how to determine whether it should be applied or not. This plunker demonstrates how I would accomplish this. You basically need to return two different link functions from the compilation phase; one if your directive should be applied (in this case adding a label before the input), and a different one if it should be skipped. You are then free to use that as an argument to a separate directive. This may not work if your directive needs to do things like transclusion or isolated scopes (things that angular doesn't like two directives on the same element to do).
I'd be very sparing with how you use this, however, as it will create an inconsistent API for other developers who may be working with this code. They may not know when the directive will apply and when it won't.
Is there a built-in method to AngularJS to remove the automatically created watch on a value inserted into a template via curly braces.
For example:
<span>{{someVal}}</span>
In my case, someVal is never going to be changed after it's loaded the first time. I don't need the watch code listening for changes. I'm trying to speed up a page's performance that has a rather large table - some values the user can edit but most are read-only values.
I'm not setting up a watch manually so I don't have a reference to the deregistration method for each value. Do I need to write a custom directive to achieve this?
A buddy of mine found this set of directives for this exact purpose.
https://github.com/abourget/abourget-angular
I have recently found a better way of doing it as it's built in the angular:
<span>{{::someVal}}</span>
More information here: https://docs.angularjs.org/guide/expression