AngularJS ng-click work - javascript

I'm trying to show some details about a list of procedures using an AngularJS function. Every procedure is identified by a unique ID so I use it as a parameter in the function.
If I use this line of code it works
<a ng-click="showDetails(1)">Show Details</a>
While using this one it doesn't work
<a ng-click="showDetails({{1}})">Show Details</a>
Shouldn't everything inside double braces be solved?
EDIT: seems obvious but, given the comments, it isn't...
This is an example to understand why argument isn't fine this way, in my production version I need to perform much advanced calculations that writing 1...

When you're calling a directive, such as ng-click, you are already evaluating any JS you throw inside it because they accept an expression.
So, if you try calling ng-click="showDetails({{1}})" it's the same as calling a function with a JS object {} wrapping another object {1}. Where 1 is just an usual string/number
You could take a further read into this one: Difference between double and single curly brace in angular JS?
[EDIT] I guess this link could help you even more than the previous one: How to get evaluated attributes inside a custom directive

Related

Angular2 pass html to component

I am trying to create a component which displays a code example for a given component. The component shall be passed as HTML to the code-example component and be rendered once normally but also have its code displayed below.
When trying to fetch the code from <ng-content> in ngOnInit, Angular already started rendering the component, which means that I do not get the original code between the tags.
Passing the code via input does not work out, as the components may use single and double quotes which will cause problems when binding the data.
What I also tried is passing the code escaped to the component like
<code-example>
<component></component>
</code-example>
To unescape it and render it afterwards, which did not work out for me as I had trouble adding this pre-defined element to the DOM in a way that Angular renders it as a component.
Are there any other methods of dealing with this problem that I might be missing?
As #Timothy suggested you may try the <pre> tag.
If you also want to highlight the syntax of your code I can recommend a third party module called ng2-prism.
This is a library that supports multiple languages and is quite easy to use.

Transcluding without running digest on contents (passing raw HTML) in Directive

I am trying to pass raw HTML inside a directive for later transclusion (when I open a modal - I will use the HTML to populate it)
The problem is - that if I do it like this, the contents of dialog-body get run and the ng-repeat is implemented, which means when I pass the template along, it gets run again causing an ahem stack overflow.
Is there a way for me to use transclusion or something else to pass the inner HTML without running any digest on it?
<dialog-body>
<div ng-repeat="item_value in item.values">
{{item_value.string}}
</div>
</dialog-body>
By the way, I figured out how to get this done.
Angular was running ng-repeat on the initial code, then re-running it once I used it later on. To avoid this - I did this to skip the first ng-repeat run:
<dialog-body ng-non-bindable>
<div ng-repeat="item_value in item.values">
{{item_value.string}}
</div>
</dialog-body>
This meant that I was only passing the actual HTML and not running Angular on it. I then used a querySelector to find all the ng-non-bindable attributes and remove them. Seems to work fine.
Hope this helps someone!

Properly resolving variable in HTML

So I have a some HTML where I am pulling a value from a file and using it for a link, like so:
page
Now I need a popup to display that page when clicked, using a basic script and a line like this:
page
However, I need the popup page value to be pulled from the file as well, so something like this:
page
But the problem I am having is that the variable does not resolve in the popitup() call, I assume because of the apostrophes basically telling it to take that literally. What could fix this and make it resolve?
This is in conjunction with AngularJS
I'm going to assume that the first snippet you posted. If it works, great; this answer should work for you. If not, well, I don't know - more information would be needed, like a fiddle illustrating the problem or know what templating engine you're using.
Since the function "popitup" needs the save value as the href of the link, why not pass in the href of the link?
page
ngClick is the way to deal with that kind of things if you are using Angular.
This was anserwed here, and if you really need the onclick attribute: how to pass angular js variable inside onclick function as parameter

Variable passed by = into isolate scope not binding

I'm working on a directive I hope to make public for use and ridicule, and I've found a pretty major issue I can't figure out if its my controller code or my directive.
I have a variable I pass to the directive via '=' in the isolate scope. If I pass the variable as a child object of an object, it works perfectly in any case, but when I pass it a top level variable, it works in one case, any changes the directive makes are reflected in the parent scope, while in the second, any changes the directive makes are not seen in the parent
In the working case, I don't define the variable before it gets sent to the directive. It's modified in the directive, and shows up properly in the parent scope.
In the non-working case, it is defined before being sent to the directive, but none of the changes in the directive show in the parent scope.
In both case, I tried both predefining and removing any initial definitions of the variable being sent to the directive; in the working case, it continued to work, in the non-working case, no progress was made.
This is the first time I've seen a '=' scoped variable not change based on changes made in the directive, and I'm at a loss.
Unfortunately, I don't have a working case to show you. I put the code into a plnkr to show a co-worker, and you can see all my code to see if there's something stand out wrong, and while I'll try to put together a working case, it involves an API, a bunch of code around it, and I suspect my simplifying it to make a working plnkr will solve the problem and not help figure out the issue I'm having. Unfortunately, I don't even know what code I should show you directly, as SO only lets me link plnkrs if I have code here.
Basically I have a directive
<combobox data="dataList" value="result"></combobox>
Data can be sent in as an array of strings or an array of objects of this format: { 'value': 'car_3', 'display': 'BMW' }. Value returns as an object of the same type (if an array of strings is passed to data, its converted to objects in that format).
In case 1, result comes back with the data the directive sets, in case 2, it never changes (it maintains it's initial value.
http://plnkr.co/edit/hUCuZuBu9BUbdwD0V6AO
In the plnkr, main.js contains my directive, and both case files show how the directive is called in the HTML. I'm sure there's some junk code in there, as I've been debugging this like crazy...
hmm without seeing your code it sounds an awful lot like you're dealing with the common (super frustrating!) problem of js primitives being duplicated inside of child scopes, causing an unexpected non-bi-directional chain of binding. Are you using dot syntax on your model to force prototype?
Check out:
"Not having a dot in your ng-model (or other places you need it!)"
http://nathanleclaire.com/blog/2014/04/19/5-angularjs-antipatterns-and-pitfalls/

AngularJS : Why ng-bind is better than {{}} in angular?

I was in one of the angular presentation and one of the person in the meeting mentioned ng-bind is better than {{}} binding.
One of the reason, ng-bind put the variable in the watch list and only when there is a model change the data get pushed to view, on the other hand, {{}} will interpolate the expression every time (I guess it is the angular cycle) and push the value, even if the value changed or not.
Also it is said that, if you have not much data in on the screen you can use {{}} and the performance issue will not be visible. Can someone shed some light on this issue for me?
Visibility:
While your angularjs is bootstrapping, the user might see your placed brackets in the html. This can be handled with ng-cloak. But for me this is a workaround, that I don't need to use, if I use ng-bind.
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.
I am currently building a big single page app (~500 bindings per view). Changing from {{}} to strict ng-bind did save us about 20% in every scope.$digest.
Suggestion:
If you use a translation module such as angular-translate, always prefer directives before brackets annotation.
{{'WELCOME'|translate}} => <span ng-translate="WELCOME"></span>
If you need a filter function, better go for a directive, that actually just uses your custom filter. Documentation for $filter service
UPDATE 28.11.2014 (but maybe off the topic):
In Angular 1.3x the bindonce functionality was introduced. Therefore you can bind the value of an expression/attribute once (will be bound when != 'undefined').
This is useful when you don't expect your binding to change.
Usage:
Place :: before your binding:
<ul>
<li ng-repeat="item in ::items">{{item}}</li>
</ul>
<a-directive name="::item">
<span data-ng-bind="::value"></span>
Example:
ng-repeat to output some data in the table, with multiple bindings per row.
Translation-bindings, filter outputs, which get executed in every scope digest.
If you are not using ng-bind, instead something like this:
<div>
Hello, {{user.name}}
</div>
you might see the actual Hello, {{user.name}} for a second before user.name is resolved (before the data is loaded)
You could do something like this
<div>
Hello, <span ng-bind="user.name"></span>
</div>
if that's an issue for you.
Another solution is to use ng-cloak.
ng-bind is better than {{...}}
For example, you could do:
<div>
Hello, {{variable}}
</div>
This means that the whole text Hello, {{variable}} enclosed by <div> will be copied and stored in memory.
If instead you do something like this:
<div>
Hello, <span ng-bind="variable"></span>
</div>
Only the value of the value will be stored in memory, and angular will register a watcher (watch expression) which consists of the variable only.
Basically the double-curly syntax is more naturally readable and requires less typing.
Both cases produce the same output but.. if you choose to go with {{}} there is a chance that the user will see for some milliseconds the {{}} before your template is rendered by angular. So if you notice any {{}} then is better to use ng-bind.
Also very important is that only in your index.html of your angular app you can have un-rendered {{}}. If you are using directives so then templates, there is no chance to see that because angular first render the template and after append it to the DOM.
{{...}} is meant two-way data binding. But, ng-bind is actually meant for one-way data binding.
Using ng-bind will reduce the number of watchers in your page. Hence ng-bind will be faster than {{...}}. So, if you only want to display a value and its updates, and do not want to reflect its change from UI back to the controller, then go for ng-bind. This will increase the page performance and reduce the page load time.
<div>
Hello, <span ng-bind="variable"></span>
</div>
This is because with {{}} the angular compiler considers both the text node and it's parent as there is a possibility of merging of 2 {{}} nodes. Hence there are additional linkers that add to the load time. Of course for a few such occurrences the difference is immaterial, however when you are using this inside a repeater of large number of items, it will cause an impact in slower runtime environment.
The reason why Ng-Bind is better because,
When Your page is not Loaded or when your internet is slow or when your website loaded half, then you can see these type of issues (Check the Screen Shot with Read mark) will be triggered on Screen which is Completly weird. To avoid such we should use Ng-bind
ng-bind has its problems too.When you try to use angular filters, limit or something else, you maybe can have problem if you use ng-bind. But in other case, ng-bind is better in UX side.when user opens a page, he/she will see (10ms-100ms) that print symbols ( {{ ... }} ), that's why ng-bind is better.
There is some flickering problem in {{ }} like when you refresh the page then for a short spam of time expression is seen.So we should use ng-bind instead of expression for data depiction.
ng-bind is also safer because it represents html as a string.
So for example, '<script on*=maliciousCode()></script>' will be displayed as a string and not be executed.
According to Angular Doc:
Since ngBind is an element attribute, it makes the bindings invisible to the user while the page is loading... it's the main difference...
Basically until every dom elements not loaded, we can not see them and because ngBind is attribute on the element, it waits until the doms come into play... more info below
ngBind
- directive in module ng
The ngBind attribute tells AngularJS to replace the text content of the specified HTML element with the value of a given expression, and to update the text content when the value of that expression changes.
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 AngularJS compiles it. Since ngBind is an element attribute, it makes the bindings invisible to the user while the page is loading.
An alternative solution to this problem would be using the ngCloak directive. visit here
for more info about the ngbind visit this page: https://docs.angularjs.org/api/ng/directive/ngBind
You could do something like this as attribute, ng-bind:
<div ng-bind="my.name"></div>
or do interpolation as below:
<div>{{my.name}}</div>
or this way with ng-cloak attributes in AngularJs:
<div id="my-name" ng-cloak>{{my.name}}</div>
ng-cloak avoid flashing on the dom and wait until all be ready! this is equal to ng-bind attribute...
You can refer to this site it will give you a explanation which one is better as i know {{}} this is slower than ng-bind.
http://corpus.hubwiz.com/2/angularjs/16125872.html
refer this site.

Categories

Resources