how to hide an element before applying data bind - angularjs

I want to hide a text message while the js is loading and data binding is not yet applied. I have tried something like this but its always hiding the message
.hide { display: none; }
<div class="hide" ng-hide="haveRecords">No Records found</div>
If I remove the class hide from div. then this element is shown for some milli-seconds before the data binding is applied. How to fix it?

This is what ngCloak is for.
You can use it like this:
<head>
...
<style>[ng-cloak] {display: none !important;}</style>
</head>
<body>
...
<div ng-cloak ng-hide="haveRecords">No Records found</div>
NOTE: The style in the head is only required if you include the AngularJS script at the end of body (which is a good idea anyway).

You should use ngCloak
The ngCloak directive is used to prevent the Angular html template from being briefly displayed by the browser in its raw (uncompiled) form while your application is loading. Use this directive to avoid the undesirable flicker effect caused by the html template display.
Code
<div ng-hide="haveRecords" ng-cloak>No Records found</div>

Related

How do you prevent ng-bind-html from adding closing tags?

I have two pieces of HTML I need to output the first is an opening tag of a div that represents my header, the second is the closing tag of the div that will represent the footer. Between the two I have dynamic content that I cannot control. I want headerHTML to include the opening div and CSS class and the footer to close the header div to wrap all the content that will be in between.
<ng-bind-html ng-bind-html="headerHTML" />
<ng-bind-html ng-bind-html="footerHTML" />
So after render it should look like:
<div class="myCSSClass">
A bunch of dynamic content created between the two binds
</div>
However, what happens is this:
<div class="myCSSClass">
</div>
A bunch of dynamic content created between the two binds
<div>
</div>
The problems is that it is auto adding the closing tag for the headerHTML when its not part of the content. This causes the page to render incorrectly. Is there another way to inject HTML content without it adding closing tag?
Under the hood, the ng-bind-html directive uses Node.appendChild. This means that it must attach a complete element. If the HTML omits a closing tag, the browser has to close the element. This is the way the DOM works. The browser can't split opening and closing tags between two .appendChild operations.
To do what you want, use a component that transcludes contents:
app.component("myComponent", {
bindings: {
headerHtml: '<',
footerHtml: '<',
},
template: `
<div class="myCSSClass">
<div ng-bind-html="$ctrl.headerHtml"></div>
<div ng-transclude></div>
<div ng-bind-html="$ctrl.footerHtml"></div>
</div>
`,
transclude: true
});
Usage:
<my-component header-html="headerHTML" footer-html="footerHTML">
This content will be sandwiched between header and footer.
</my-component>
For more information, see
AngularJS ng-transclude Directive API Reference.
AngularJS Directive Definition Object API Reference - transclude

Replace ui-view with the loaded content

I have multiple views like here : http://www.funnyant.com/angularjs-ui-router/
And I load them in my page like this
<div data-ui-view="content"></div> --- 75% width
<div data-ui-view="sidebar"></div> --- 25% width
Now, when the content is loaded, I want the loaded content not load inside these ui-view divs, but to replace them. Is it possible ? because if they don't replace then in my situation the float won't work and the sidebar shows bellow the content.
Help please
thanks
Using Bootstrap rows would this achieve your aim?
<div class="row">
<div class="col-md-9" ui-view="content"></div>
<div class="col-md-3" ui-view="sidebar"></div>
</div>
This is not possible and would be undesirable as it would leave you unable to change states. A simple workaround would be to add the width/float styles directly to the ui-view divs.
If you are determined to make it work you could create a custom directive wrapper like the solution provided here.
Try adding your desired sizes to the style of the containers.
<div data-ui-view="content" style="width: 75%;"></div>
<div data-ui-view="sidebar" style="width: 25%;"></div>

AngularJS - looking to add and remove an iframe based on dom events

I would like to add an iframe to a page when certain links are clicked and remove it when other mouse events happen on the page. From what I can see, it seems that using an AngularJS directive would be the best way to do this. What I'm not sure about is what is the best way to format the directive. I'm thinking of making the directive at the attribute level...something like this:
<div myIframeDirective></div>
What I'm not sure of is the best way of removing/adding the directive contents (an iframe and a header above it) when various click events happen on the main page. Not looking for anyone to write the code for me...just looking for examples of how this can be best accomplished.
You should be using ng-if.
<iframe src="http://www.example.com/" ng-if="showIframe"></iframe>
<button ng-click="showIframe = !showIframe">Click me to show/hide the iframe</button>
Here's a working example:
var app = angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<iframe src="http://www.example.com/" ng-if="showIframe"></iframe>
<button ng-click="showIframe = !showIframe">Click me to show/hide the iframe</button>
</div>
In Angular, ng-if will remove the iframe from the DOM if it is false.
This means the URL will NOT be requested until ng-if is true.
<iframe ng-if="frameDisplayed" ng-src="{{src}}"></iframe>
And use the link
Toggle
Then in your controller, you can control what your iframe display:
$scope.src = 'https://angularjs.org';

Do I need to put AngularJS in the <head> if I want to hide {{ xxx }} from showing on my page?

I have HTML like this:
<div id="top"
ng-hide="app.stateService.displayModal">
<div>{{ app.userService.data.name }}</div>
</div>
// Body HTML here. No images are loaded. Just Divs
<script src="Scripts/jquery-2.1.1.min.js"></script>
<script src="/Scripts/angular.js"></script>
Now the page briefly shows {{ app.userService.data.name }}.
If I want this to not show then do I have to have AngularJS in the head of my document? The reason I placed AngularJS at the end was because I wanted to have the page appear as quickly as possible.
Can someone advise me about this and also tell me how I can make the {{ xxx }} hidden when the page first loads up.
You could use ng-cloak to hide any elements until it get compiled.
<div id="top" ng-cloak
ng-hide="app.stateService.displayModal">
<div>{{ app.userService.data.name }}</div>
</div>
The CSS rules to hide the elements with ng-cloak will be added automatically by angular.js.
If that isn't fast enough you could add the css rules yourself at the head:
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
Or using the angular-csp.css file.
Also see: ngCloak documentation
you can do it in two ways -
ng-bind
OR
ng-cloak
{{ app.userService.data.name }}
Either way, you {{}} won't show up. no need to put angular.js inside head.
This is the role of the ng-cloak directive used as a css class.
Check doc: https://docs.angularjs.org/api/ng/directive/ngCloak
You better use ng-bind
<span ng-bind="app.userService.data.name"></span>
instead of {{app.userService.data.name}}.
This will avoid that flickering.

ng-cloak and ng-show flashes the hidden element on screen

I have a div element that I only want to be show when my list of items empty. So I put in the following(in haml):
#no-items.ng-cloak{ :ng_show => "items.length <= 0", :ng_cloak => true }
However, even after I've done that the element is still flashing on the screen. Then I saw Angularjs - ng-cloak/ng-show elements blink, but even after adding the following in my CSS, the blink still occurs.
[ng\:cloak], [ng-cloak], .ng-cloak {
display: none !important;
}
Any ideas what I am doing wrong?
You can put ng-hide in the class without affecting how the JS will work once loaded. However, it is useful to put it there so that CSS takes it into account while waiting for the JS to load.
<div data-ng-controller="RoomsController">
<div ng-cloak class="ng-cloak ng-hide" data-ng-if="visible" >
Some text
</div>
</div>
Ensure the ng-cloak CSS shown above is being loaded at the beginning of your page.
This should be all you need to do:
<div ng-hide="items.length" ng-cloak>no items</div>
Sample fiddle.
None of the solutions worked for me. The only solution I found is the following:
In each controller, add:
$scope.$on('$viewContentLoaded', function () {
$scope.completed = true;
});
and in the html of each view , add ng-if="completed" to the topmost element. For example:
<div ng-if="completed">
Note: the problem is restricted to firefox and ui-router. There, ng-cloak is ignored and there is no css workaround. The only solution that worked for me is the one I gave above.
There's currently an open issue for this:
https://github.com/angular/angular.js/issues/14015
This workaround worked for me:
.ng-hide.ng-hide-animate {
display: none !important;
}

Resources