Set AngularJS Directive load order not defined on a single DOM - angularjs

This is my first post here, usually I can find what I’m looking for before I ask but, if I missed the same question/answer elsewhere sorry. Anyway this is what I have.
I’m working on an Angular project where we have multiple directives not defined on a single DOM like this below(not exactly but a good example)
<div class=”Directive-holder”>
<div Directive-1 ng-show="showDirective1"></div>
<div Directive-2 ng-show="showDirective2"></div>
<div Directive-3 ng-show="showDirective3"></div>
<div Directive-4 ng-show="showDirective5"></div>
(Multiple more below)
</div>
Now when I run the project I need these to load in order
Directive-1
Directive-2
Directive-3
Directive-4
But when they run they run random every reload is there a way to set the order of these to stay 1-4 on every load?
It looks like priority: 0,  only work on multiple directives defined on a single DOM,

Related

Best approach to change background image in AngularJs at runtime

I want to create generic feature that allows me to change background image of any section. After going through options provided I found these two approaches. Want to choose best approach to change image because on single page I want multiple times change background facility. It will be available to four to five sections.
Approach
Using Directive check this stack overflow link.
Also there is another approach of angular scope variables that we can updates at runtime.
<div ng-style="{'background-image': 'url(/images/' + backgroundImageUrl + ')'}"></div>
Required Usage ( With respect of Directive )
<body>
<section backgroundImage url="{{backgroundImageUrl1}}">
...
</section>
<section backgroundImage url="{{backgroundImageUrl2}}">
...
</section>
<section backgroundImage url="{{backgroundImageUrl3}}">
...
</section>
<section backgroundImage url="{{backgroundImageUrl4}}">
...
</section>
</body>
As shown above I am going to update background-image attribute for each section. If these property is set inside CSS file, it will reduce time to load images i.e. If we directly add inline css styling in HTML, all images will loaded on DOM load. It will make extra request to server to get images and load them in DOM. I wanted to follow strategy that will reduce loading time in my SPA(Single Page Application).
I think going with <div ng-style="{'background-image': 'url(/images/' + backgroundImageUrl + ')'}"></div> should be more effective.
You dont introduce another layer of complexity, directives create scopes, which are watched and digested, also directives must be compiled in the begining.
Using symple ng-style together with some specific url from controllers property shoudl only do request for that particular active image. Because of that i think it should be the optimal solution.

Why is my angular grid so slow?

So, I have made some custom directive which draws kind of a data-grid, based on floated divs (because nested flex implementation in FF sucks - but it's not the point).
How it works :
I pass some data collection to the directive via something like <the-grid data-list="parentController.displayedRows">
Inside this first directive, I have columns via something like <a-grid-column data-value="row.value"></a-grid-column> with many attributes I won't precise here.
The data-value value can be a direct expression, bound to the row on which the the-grid directive controller is ng-repeating in order to display each columns, or a function which have to be $eval-uated in order to display the intended value from the parentController.
In my <the-grid> directive controller, I have the rendering template of my grid which make a nested ng-repeat div (first one on the rows of the data-collection, second one on the columns, created in the directive), it looks like :
<div data-ng-repeat="row in list">
<div data-ng-repeat="cell in theGridColumns"
data-ng-bind-html="renderCell(row, cell)">
</div>
</div>
I have some keyboard nav in order to quickly select a row or navigate within pagination or many tabs, which does nothing more than applying some class on the selected row, in addition to update some "selectedRowIndex".
I'm using angular-vs-repeat in order to have the minimum of row divs in my DOM (because the app is running on slow computers). This works well.
The problem is that every time I'm hitting some "up" or "down" key on my keyboard, Angular is "redrawing" EVERY cells of the list.
So, let's suppose I've 200 rows in my data list, and 7 columns for each rows. First load of the page, it passes ~3000 times in the renderCell() function. Ok , let's accept that (don't really understand why, but ok).
I hit the down key in order to go to the second line of my list. It passes ~1100 times in the renderCell() function.
So yes, the result is very slow (imagine if I let the down arrow key pressed in order to quick navigate within my rows)... I can't accept that. If someone could explain that to me... Any help would be greatly accepted :)
If I make the same thing without a directive (direct DOM manipulation, with columns made by hand and not in a ng-repeat within a ng-repeat), every thing is smooth and clean.
Yes, I've look into every angular grid on the market. No one is satisfying me for my purpose, that's why I've decided to create my own one.
And no, I really can't give you some JSFiddle or anything for the moment. The whole app is really tentacular, isolating this is some kind of complicated).
Try to use bind once (angular 1.3+)
<div data-ng-repeat="row in ::list">
<div data-ng-repeat="cell in ::theGridColumns"
data-ng-bind-html="::(renderCell(row, cell))">
</div>
</div>

AngularJS insert invalid HTML

I have an app that requires HTML to be pieced together from different APIs. Rather than getting into specifics there, let me just say that we have tried getting away from that many times but in the end the best answer always end up being what we currently have. Hopefully that changes someday but for now it's working great.
Currently, the HTML is parsed together as a string server-side using NodeJS and sent across the wire as complete HTML to be rendered. I'm in the process of adopting AngularJS, and while I'm loving it I am stuck on this issue-- how can I use Angular templating to insert invalid HTML at times?
The server will return three JSON fields: leadingHTML, trailingHTML, and copy. The copy field is always valid HTML, but leadingHTML and trailingHTML can sometimes return invalid HTML. When all three are added together, valid HTML results.
Let me illustrate:
leadingHTML='<figure>';
copy = '<img src="img1.jpg"/><img src="im2.jpg"/><figcaption>I love AngularJS</figcaption>';
trailingHTML='</figure>';
As you can see, if you add those together you will get the valid HTML that is required to be displayed. It's pretty easy to make the fields trustworthy HTML in Angular:
for (i in data.results){
data.results[i].copy=$sce.trustAsHtml(data.results[i].copy);
data.results[i].leadingHTML =$sce.trustAsHtml(data.results[i].leadingHTML );
data.results[i].trailingHTML =$sce.trustAsHtml(data.results[i].trailingHTML );
}
And then render the copy in my view:
<div ng-repeat='i in data.result'>
<p ng-bind-html='i.copy'></p>
</div>
But I need a way that does what this looks like it would do, but the leadingHTML and trailingHTML scope variables get render as strings:
<div ng-repeat='i in data.result'>
{{ i.leadingHTML }}
<p ng-bind-html='i.copy'></p>
{{ i.trailingHTML }}
</div>
Is the best answer here to build the template via javascript? Would that even work?
Are you able to pre-process your data so that you do have valid HTML?
var item;
for (i in data.results){
item = data.results[i];
item.content = $sce.trustAsHtml(item.leadingHTML + item.copy + item.trailingHTML);
}
Then you can just bind to the combined content in the view:
<div ng-repeat='i in data.results'>
<div ng-bind-html='i.content'></div>
</div>
Edit:
Yes, this will allow you to embed expressions in your HTML content.
In fact, you will need to be careful that you aren't opening yourself up to security exploits in the trusted HTML content (see the example at the bottom of the page for the $sce service).
Using $sce.trustAsHtml in this way is roughly equivalent to loading a directive's templateUrl from your site, so the security considerations around that are probably the same. See the "How does it work?" and
"Impact on loading templates".

angular js reloading view

I'm using Angular JS and Angular IU-Router in my project and using a lot of ui-views. I have a situation where I need to change the language of the site, therefore I need to swap my ui-view's model to another model with the relevant language. I already have a service that detects the relevant model and passes it into the ui-view's controller. So if I can reload the ui-view, then in theory my problem would be solved.
I recall reading something about automatically reloading a ui-view (or possibly an ng-view) and re-instantiating its controller, but after much searching I haven't been able to find that information again.
Does anyone know what it is I'm looking for?
1 Take a look at angular-translate
https://github.com/PascalPrecht/angular-translate
2 In your case, add some if-else control ( ng-if, ng-switch etc. ) in the outer div, use the same subview in the inner div. Then change the settings.currentLang when the language changes may cause the subview reload (not tested).
<div ng-controller="containerCtrl">
<div ng-if="settings.currentLang=='en'">
<div ui-view='subview'></div>
</div>
<div ng-if="settings.currentLang=='ja'">
<div ui-view='subview'></div>
</div>
</div>

Stop AngularJS inserting <span class="ng-scope"></span> using ng-include

I'm using the Foundation layout framework, which automatically floats the last sibling of .column to the right and I really appreciate this is a behaviour. However, AngularJS takes it upon itself to insert span.ng-scope after every div.column, which somehow causes browsers to consider the last span the last sibling of .column (even though it is not).
Specifically the css in Foundation responsible for this is:
[class*="column"] + [class*="column"]:last-child { float: right; }
As I understand it, [attribute*="substring"] should select only siblings that match, so, for the above, only elements whose class attribute contains column (including columns). I would think a span tag whose class attribute that does not contain column should not match (and thus be ignored by :last-child). However, this does not seem to be the case.
Regardless, the span is causing the problem:
Angular buggering it up (jsfiddle)
Works fine without Angular (same jsfiddle, no ng-include)
Is there a way to configure angular to stop inserting those span tags? I would, begrudgingly, modify the css selector to somehow ignore all span tags; however I might eventually need/want to use a span tag.
Since you indicated the div can be moved inside, this works:
<ng-include src="'main.tmpl'"></ng-include>
Then in your template:
<div class="row">
<article id="sidepanels" class="four columns">
...
</div>
I'm not aware of any way to prevent angular from inserting the span tags (I think it keeps track of scopes that way -- for garbage collection).
Also you can try my version of include directive that does not creates a scope: Gist source.
As no scopes are created, AngularJS should not create additional element to mainain scope (it actually use data attributes to store link to scope).

Resources