AngularJS: How to preload images at first page start in angularjs - angularjs

I have a json object with images urls and I display those images with ng-repeat. My problem is that images are flickering when page is loaded for first time. I would like to display preloader (css spinner) and preload all images and than apply ng-repeat.
-> Plnkr

Easy doing while using angular-easy-image-preloader like in this demo plnkr.
View
<div class="gallery" ng-controller="galleryController">
<img ng-if="loaded" class="appear" ng-repeat="picture in pictures" ng-src="{{picture}}" alt="">
<div ng-if="!loaded">
<div id="preloader-overlay">
<div id="preloader"></div>
</div>
</div>
</div>
AngularJS controller
/* Gallery Controller */
app.controller('galleryController', function(
$scope,
$timeout,
preloader
) {
$scope.loaded = false;
$scope.pictures = [
"http://www.d3d.sk/images/MK2_Granade_full.png",
"http://www.d3d.sk/images/aberry-logo.jpg",
"http://www.d3d.sk/images/logo-aberry.png",
"http://www.d3d.sk/images/Crystal_balls.jpg",
"http://www.d3d.sk/images/Purple_sun.jpg",
"http://www.d3d.sk/images/planets.jpg",
"http://www.d3d.sk/images/d3d.jpg",
"http://www.d3d.sk/images/bpg-logo.png",
"http://www.d3d.sk/images/Logo - Bukona.jpg",
"http://www.d3d.sk/images/sky_up_fire.jpg",
"http://www.d3d.sk/images/plexus.jpg",
"http://www.d3d.sk/images/dch.jpg",
"http://www.d3d.sk/images/Dimonsium-front-a.jpg",
"http://www.d3d.sk/images/DWTS-3.jpg",
"http://www.d3d.sk/images/Dwts-redesign-1.png",
"http://www.d3d.sk/images/diplom.jpg",
"http://www.d3d.sk/images/Genessis.jpg",
"http://www.d3d.sk/images/Genessis - logo-final.jpg",
"http://www.d3d.sk/images/Genessis - logo.jpg",
"http://www.d3d.sk/images/Goholor.jpg",
"http://www.d3d.sk/images/iron.jpg",
"http://www.d3d.sk/images/bg_body3.jpg",
"http://www.d3d.sk/images/bg_body4.jpg",
"http://www.d3d.sk/images/lampa-2.png",
"http://www.d3d.sk/images/MaxEnergy-design.jpg",
"http://www.d3d.sk/images/North-first-2.jpg",
"http://www.d3d.sk/images/North Side Dres - ver 1c.jpg",
"http://www.d3d.sk/images/oznamko-16.jpg",
"http://www.d3d.sk/images/oznamko-17.jpg",
"http://www.d3d.sk/images/Verzia4e.jpg",
"http://www.d3d.sk/images/Svk-dres.jpg",
"http://www.d3d.sk/images/Rool-up04bc.jpg",
"http://www.d3d.sk/images/Senica-letak-maly.jpg",
"http://www.d3d.sk/images/Merkur - dizajn - 4.jpg",
"http://www.d3d.sk/images/Trades-world-2.jpg",
"http://www.d3d.sk/images/web-1.jpg",
"http://www.d3d.sk/images/web-3.jpg",
"http://www.d3d.sk/images/web-5.jpg",
"http://www.d3d.sk/images/web-7.jpg",
"http://www.d3d.sk/images/web-8.jpg",
"http://www.d3d.sk/images/web-10.jpg",
"http://www.d3d.sk/images/web-11.jpg",
"http://www.d3d.sk/images/vizitka.jpg"
];
preloader.preloadImages($scope.pictures).then(function() {
$scope.loaded = true;
},function() {
console.log('failed');
// Loading failed on at least one image.
});
});

Related

Phantom Js with Node and Angular - ng-repeat not rendering

I have an angular App, using angular-ui-router.
Page I have built looks fine.
I am trying to take a snapshot of the html and create a pdf.
To do this, I am using Phantom.
I can trigger and create a PDF fine, but it doesn't render my ng-repeat section of the HTML.
My HTML:
<div>{{vm.hello}}</div>
<div class="row">
<div class="col-xs-2">Heading</div>
</div>
<div class="row" ng-repeat="record in vm.records">
<div class="col-xs-2">Space</div>
<div class="col-xs-2" ng-bind="record.id"></div>
</div>
My controller triggers on load to populate vm.records.
vm.hello is hardcoded and renders fine.
Nothing in my ng-repeat loads.
My Node js code:
var phantom = require('phantom');
function pdf(req, res) {
console.log('pdf function entered');
var url = "http://myapp.com/page";
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
page.viewportSize = {
width: 1400,
height: 1024
};
page.property('onLoadFinished', function(status) {
console.log("Load Finished with status " + status);
});
page.open(url).then(function(status) {
page.render('test.pdf', {
format: 'pdf',
quality: '100'
}).then(function() {
console.log("File Created");
page.close();
ph.exit();
});
});
});
});
res.status(200).send();
}
Can anyone shed some light as to why the ng-repeat won't work? I've tried adding delays in and such based on other questions/answers, but just can't seem to get it working.
In your controller you have to call
window.callPhantom();
when the render is completed
Next is you have to call it inside $timeout like this
$timeout(function(){
window.callPhantom();
return;
})
to avoid call it before binding

WP Rest API + AngularJS : How to grab Featured Image for display on page?

I am accessing Wordpress data through an HTTP REST API plugin (this wordpress plugin: http://v2.wp-api.org/). I know how to grab my post title, but how do I display the featured image associated with that post using this plugin? My test shows the post title and the featured image ID, but I am unsure how to display the actual image. Test Example.
Here's my code:
<div ng-app="myApp">
<div ng-controller="Ctrl">
<div ng-repeat="post in posts | limitTo: 1">
<h2 ng-bind-html="post.title.rendered"></h2>
<p>{{ post.featured_image }}</p>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-sanitize.min.js"></script>
<script>
var app = angular.module('myApp', ['ngSanitize']);
app.controller('Ctrl', function($http, $scope) {
$http.get("http://ogmda.com/wp/wp-json/wp/v2/posts").success(function(data) {
$scope.posts = data;
});
});
</script>
To get featured images response, please add _embed on the query string. example:
http://demo.wp-api.org/wp-json/wp/v2/posts/?_embed
Then, access the featured images in returned JSON response using _embedded['wp:featuredmedia'][0].media_details.sizes.thumbnail.source_url
var app = angular.module('myApp', ['ngSanitize']);
app.controller('Ctrl', function($http, $scope) {
$http.get("http://ogmda.com/wp/wp-json/wp/v2/posts?_embed").success(function(data) {
$scope.posts = data;
var firstFeaturedImageUrl = $scope.posts[0]._embedded['wp:featuredmedia'][0].media_details.sizes.thumbnail.source_url;
});
});
A better way would be to integrate the URL of the featured image into the json response so that you get it all in a single request. You can add the following code (inside your-theme/functions.php) to achieve this:
//Get image URL
function get_thumbnail_url($post){
if(has_post_thumbnail($post['id'])){
$imgArray = wp_get_attachment_image_src( get_post_thumbnail_id( $post['id'] ), 'full' ); // replace 'full' with 'thumbnail' to get a thumbnail
$imgURL = $imgArray[0];
return $imgURL;
} else {
return false;
}
}
//integrate with WP-REST-API
function insert_thumbnail_url() {
register_rest_field( 'post',
'featured_image', //key-name in json response
array(
'get_callback' => 'get_thumbnail_url',
'update_callback' => null,
'schema' => null,
)
);
}
//register action
add_action( 'rest_api_init', 'insert_thumbnail_url' );
Then in your view, you can use
{{ post.featured_image }}
Note: To get the same image in different sizes, use above wp_get_attachment_image_src function that accepts any valid image size, or an array of width and height values in pixels as its second parameter.
I found a very easy way to do this.
Just download the new Wordpress plugin called Better Rest API Featured Image.This plugin adds a better_featured_image field to the post object that contains the available image sizes and urls, allowing you to get this information without making a second request.
You can replace <p>{{ post.featured_image }}</p> with this <img ng-src="{{post.better_featured_image.source_url}}" />

Angularjs how can I reload the content

I have this code that loads the content when the page load,
Now I want to know how to reload the content by clicking the button.
Can you show me how to do it with example please?
Javascript code:
.controller('InterNewsCtrl', function($scope, NewsService) {
$scope.events = [];
$scope.getData = function() {
NewsService.getAll().then(function (response) {
$scope.events = response;
}), function (error) {
}
};
$scope.getData(); // load initial content.
})
Html code:
<ons-toolbar fixed-style>
<div class="left">
<ons-back-button>Voltar</ons-back-button>
</div>
<div class="right">
<ons-toolbar-button><ons-icon icon="ion-android-refresh"></ons-icon></ons-toolbar-button>
</div>
<div class="center">Internacional</div>
</ons-toolbar>
I think you're asking how to just retrieve new events from the backend. If that's correct, you don't need to reload the entire page.
You already have a function called getData which goes and retrieves you data via your service. Assuming your service doesn't cache the data, just call getData from your button:
<ons-toolbar-button ng-click="getData()"><ons-icon icon="ion-android-refresh"></ons-icon></ons-toolbar-button>
P.S. if you do explicitly have the cache set to true in your service, you can remove the cached data with $cacheFactory.get('$http').removeAll();.
For reloading same page in angular Js without post back
first remove that url from template cache if you call $route.reload() without removing it from $templateCache it will get it from cache and it will not get latest content
Try following code
$scope.getdata=function()
{
var currentPageTemplate = $route.current.templateUrl;
$templateCache.remove(currentPageTemplate);
$route.reload();
}
and Call it as following
<input type="button" ng-click="getdata();" value ="refresh"/>
Hope this will help
Please reffer this

Is there any way to delay ng-view?

I have layout where I have:
<li ng-click="GetLoader();">ACCOUNT</li>
<li ng-click="GetLoader();">SETTINGS</li>
On the index page, I have a menu and ng-view where I can change pages on a click
Also included on the index page is a spinner.
<div class="loading" ng-show="ticketloading" ng-init="GetLoader()">
<div>
<img class="spinner" ng-src="~/Images/ajax-loader.gif" />
</div>
</div>
In my script I have -
$scope.GetLoader = function() {
$scope.ticketloading = true;
loader.css("z-index", "1");
}
My problem is that when a user clicks on "Account" it gets loaded, but just for few milliseconds. Then it changes to all blank. I receive data from ng-view. My question is how can I delay showing ng-view to show the loader a little bit longer.
Thanx in advance!
First of all you should avoid using DOM manipulations in controller. In your case it's better to use declarative ngClass directive to set opacity.
Then your actual issue is that you don't want to use static setTimeout to hide loaded, but rather listen $routeChangeSuccess:
$rootScope.$on('$routeChangeSuccess', function() {
$rootScope.ticketloading = false;
});
and use this loading flag in template like you are currently doing.
You can put above event listener in run block for example.
You can add property in your controller, for example dataLoading and add ng-if attribute to ng-view like this:
layout
<div ng-view ng-if="!dataLoading">
controller
function loadData()
{
var self = this;
self.dataLoading = true;
dataService.loadData(params, function(){
...
self.dataLoading = false;
});
}

Embed Vimeo video using AngularJS directive

I have a partial HTML page in an AngularJS app that I'm trying to add a vimeo video to. This template has an image and play button that fades out on click to show the underlying iFrame. I also want this click trigger to play the video, so that someone doesn't have to press two play buttons.
The div in my partial page template where this is happening working version of site here:
<div id="container" >
<div id="dummy"></div>
<div id="element">
<iframe id="player" class="fade {{playerFade}}" ng-src="http://player.vimeo.com/video/{{person.video}}?api=1&player_id=player&wmode=opaque" frameborder="0" allowfullscreen></iframe>
<img id="person_photo" class="fade {{person_photoFade}}" ng-src="{{person.photo_small}}" ng-src-responsive="[ [ '(min-width: 720px)', '{{person.photo_medium}}' ], [ '(min-width: 960px)', '{{person.photo_large}}' ], [ '(min-width: 1200px)', '{{person.photo_extralarge}}' ] ]" />
<a id="playButton" ng-click="playing=true" class="fade {{playButtonFade}}" ><img src="img/furniture/play.png" class="img_play" alt="play button"/></a>
</div>
</div>
Now, I did get this to work once, but that was with a static, non-Angular web page. The code I used to interact with the Vimeo API is something I took from SO#8444240. They were trying to figure out preloading. Since I have so many videos, I'm not interested in that, I just used this code to get my button interacting with my video.
I tried putting this script into my index.html page, but since it is removed from Angular, it doesn't work at all. I think I need a directive. Here is the current script code I have:
<script>
//INIT Vimeo API
var vimeoPlayers = document.querySelectorAll('#player'),
player;
for (var i = 0, length = vimeoPlayers.length; i < length; i++) {
player = vimeoPlayers[i];
$f(player).addEvent('ready', ready);
}
function addEvent(element, eventName, callback) {
if (element.addEventListener) {
element.addEventListener(eventName, callback, false);
} else {
element.attachEvent(eventName, callback, false);
}
}
function ready(player_id) {
// Keep a reference to Froogaloop for this player
var container = document.getElementById(player_id).parentNode.parentNode,
froogaloop = $f(player_id);
$('#playButton a').click(function(){
$('#person_photo').fadeOut('12000');
froogaloop.api('play');
return false;
});
}
</script>
I've got a directive that controls the playbutton to fade it out (thanks to wmluke on a previous question) but I don't know how to translate this javascript into a directive. Here is my controller, too.
function DetailCtrl($scope, $routeParams, $http) {
$http.get('person.json').success(function(data) {
angular.forEach(data, function(person) {
if (person.id == $routeParams.personId)
$scope.person = person;
});
});
$scope.playing = false;
// Update the *Fade scope attributes whenever the `playing` scope attribute changes
$scope.$watch('playing', function (playing) {
$scope.playerFade = playing ? 'in' : '';
$scope.person_photoFade = playing ? '' : 'in';
$scope.playButtonFade = playing ? '' : 'in';
});
I tried writing this directive as best I could, but I don't know how to handle the ready calls to Vimeo API. It seems like there is a better way to do it in Angular.

Resources