angularjs: how to prevent from processing additional directives after ng-hide - angularjs

I have some code that is running twice even thou angularJs is rendering only one branch of it.
<div ng-Show="SomeCondition">
...
</div>
<div ng-Hide="SomeCondition">
...
</div>
AngularJs is correctly only rendering one of the divs, however it's processing both. This is leading to some performance degredation as each section is quite big. Is there a way to remove processing from one of the branch of execution?

What you're looking for is ng-switch, which will 'Conditionally change the DOM structure.' This means that the other cases will not be run, unlike using ng-hide/ng-show, which just adjust CSS.
http://docs.angularjs.org/api/ng.directive:ngSwitch
<div ng-switch on="SomeCondition">
<div ng-switch-when="true">Example</div>
<span ng-switch-when="false">Example Two</span>
<span ng-switch-when="somethingElse">Example Three</span>
<span ng-switch-default>default</span>
</div>

Related

ng-repeat fails on a p>div structure, but works for a div>div structure?

I'm maintaining a legacy product, and found a quirk that I haven't seen before in AngularJS.
As demonstrated in this Plunker, the following HTML fails to render:
<p ng-repeat="item in items">
<div>{{item.type}}</div>
</p>
while this renders just fine:
<div ng-repeat="item in items">
<div>{{item.type}}</div>
</div>
Is there any explanation as to why this might be the case?
I was rather caught off-guard with this, as I don't recall seeing anything about this in the development resources.
It most likely is due to the fact that the HTML spec specifies that for a <p> immediately followed by a <div>, the close tag is optional.
I would assume this means that somehow the browser silently ignores the presence of any explicit source-specified </p> tag. I'd guess that when ng-repeat is parsing the source, it then cannot find the end of the repeated section, and therefore cannot render as expected.

ngRepeat $scope messing with nested ngClick

So i have four progress bars that on click open and close via the close button in the top right....problem is the ngrepeat is messing with something....i've tried adding $parent to the child ngClick but it doesnt work. I've looked at all the other stack examples of this and just can't seem to figure out how to apply it to this specific situation
http://codepen.io/anon/pen/JorZoE
<div class="progress-bar repeat-animation" ng-click="showClose = false" ng-class="!showClose ? 'grow' : ''" progress-morph style="width: {{item.percent}}%" ng-repeat="item in list">
<div class="close" ng-hide="showClose" ng-click="onClickClose($event)" ><img src="close42.svg" alt=""></div>
</div>
I assumed that you wanted to open/close the bars individually.
If that's the case, your code wasn't working because you were binding all the progress bars state to the same $scope variable.
Having that in mind, I tweaked your code a little bit to make it work, and also used a more readable logic (imho).
Please take a look and let me know:
http://codepen.io/anon/pen/WbZygb?editors=101

Popovers misplaced in some HTML elements

I am working in a project where I use jQuery (~2.1.1), Bootstrap (~3.3.1), AngularJS (~1.3.4), Angular-ui-bootstrap (~0.12.0), and some more libraries. I have a small problem which is related with the popover directive of the angular-bootstrap library. This little problem is that many of the popovers are misplaced, so probably I am forgetting about something.
From the documentation and even personal tests (Plunker Example Ex. using angular 1.3.4), the popover should look aligned to the center of the HTML element, and the arrow of it should touch the element, like this:
The problem is that in my application the popover gets misplaced somehow (In this case only vertically the offset is noticeable, so it's not touching the element), as you can see next:
Another example (which is the most noticeable) is with a dynamic generated list using ng-repat, as you can see in the next picture:
<div class="col-xs-6 col-sm-2 sidebar-offcanvas"
id="sidebar-left" role="navigation">
<div class="list-group shadow-bottom" id="sideMenuTitle">
<span class="list-group-item list-group-item
disabled offcanvas-title" style="text-align: center">
<strong>Metrics</strong>
</span>
<a popover="{{metrics_messages[$index]}}" popover-popup-delay="450" popover-trigger="mouseenter"
popover-placement="top" popover-animation="true" ng-repeat="m in metrics" ui-sref="{{m.sref}}"
class="list-group-item"
ng-click="selectMetric(m)" ng-class="{active: m.selected}">{{m.caption}}</a>
</div>
</div>
PS: I included ui.bootstrap to the "global" angular module, as they suggest Angular Bootstrap Site.
The problem was related to the version where this post was made, after that version they fixed this problem.

Add another custom interpolator in Angularjs

I still want {{1+2}} to be evaluated as normal. But in addition to the normal interpolator, I want to create a custom one that I can program to do whatever I want.
e.g. <p>[[welcome_message]]</p> should be a shortcut for <p>{{'welcome_message' | translate}}</p>, or <p translate="welcome_message"></p>. That way, i18n apps would be much more convenient to write.
Is anything like that possible? I'm currently going through the angular.js source code, but the interpolation system looks pretty complicated(?). Any suggestions?
I created a directive that regex-find-replaces it's innerHTML. Basically, I can rewrite any text into any other text. Here's how I did it:
How do I make angular.js reevaluate / recompile inner html?
Now all I have to do is to place my directive-attribute, "autotranslate", in one of the parent elements of where I want my interpolator to work, and it rewrites it however I want it! :D
<div class="panel panel-default" autotranslate>
<div class="panel-heading">[[WELCOME]]</div>
<div class="panel-body">
[[HELLO_WORLD]
</div>
</div>
becomes
<div class="panel panel-default" autotranslate>
<div class="panel-heading"><span translate="WELCOME"></span></div>
<div class="panel-body">
<span translate="HELLO_WORLD"></span>
</div>
</div>
which does exactly what I wanted.
I don't think that's possible, but if you really want to save some characters you could create a function on your rootScope called t, then call it within your views:
<p>{{ t(welcome_message) }}</p>

web scraping tool or library that automatically finds text content without rules set

Is there a web scraping tool or library that auto-detects repeating HTML blocks and scrapes the text content inside the blocks, thus removing the need for human to manually input the rules - CSS selectors or xpath to find the content?
This is based on the assumptiom that modern content website is generated dynamically by server-side languages such as PHP or Python. The content is almost always rendered by a for loop in the template, hence the repeating HTML blocks can always be found. An example:
<div id="content">
<div class="blog entry">
<div class="title">
<h1>1st post</h2>
</div>
<div class="content">
<p>...</p>
</div>
</div>
<div class="blog entry">
<div class="title">
<h1>2nd post</h2>
</div>
<div class="content">
<p>...</p>
</div>
</div>
<div class="blog entry">
<div class="title">
<h1>3rd post</h2>
</div>
<div class="content">
<p>...</p>
</div>
</div>
</div>
Libraries like bautiful soap and scrapy rely on human to input the rules before the scraping can be carried out. They are not what I want.
Haven't used it, but heard about scrapely:
Unlike most scraping libraries, Scrapely doesn't work with DOM trees
or xpaths so it doesn't depend on libraries such as lxml or libxml2.
Instead, it uses an internal pure-python parser, which can accept
poorly formed HTML. The HTML is converted into an array of token ids,
which is used for matching the items to be extracted.
Scrapely extraction is based upon the Instance Based Learning
algorithm and the matched items are combined into complex objects
(it supports nested and repeated objects), using a tree of parsers,
inspired by A Hierarchical Approach to Wrapper Induction
You might want to look at my scraping library. It doesn't work automatically nor does it detect repeated parts. But it comes close, since it doesn't need rules at all and instead uses templates, which you can get directly from the html you have.
E.g. with your example above, the template to read all the posts in 2 arrays is:
<div id="content">
<div class="blog entry">
<div class="title">
<h1>{title:=.}</h1>
</div>
<div class="content">
<p>{content:=.}</p>
</div>
</div>*
</div>
You may try HTQL:
import htql;
a=htql.Browser();
p,b=a.goUrl('http://channel9.msdn.com/Blogs/Vector/Announcing-BUILD-2012');
htql.query(p, '&html_main_text');
p,b=a.goUrl('http://stackoverflow.com/questions/tagged/screen-scraping');
htql.query(p, '&html_main_text');

Resources