I'm developing a website for our company, and one of the pages contains several tabs :
I want the loading operation to be done for each tab only once and not every time I click it, because these tabs have some API calls, and reloading takes time.
What is the best way to do it? I'm using Ui-router and ui-sref to move between each tab :
<div class="col-xs-2">
<div class="panel panel-default">
<div class="list-group panel panel-default">
<a ui-sref="dashboards.firstTab" ui-sref-active="active" class="list-group-item" id="firstTab_button">
<i style="color:darkblue" class="fa fa-area-chart"></i> TAB1 </a>
<a ui-sref="dashboards.secondTab" ui-sref-active="active" class="list-group-item" id="secondTab_button">
<i style="color:darkblue" class="fa fa-line-chart"></i> TAB2 </a>
<a ui-sref="dashboards.thirdTab" ui-sref-active="active" class="list-group-item" id="thirdTab_button">
<i style="color:darkblue" class="fa fa-server"></i> TAB3 </a>
</div>
</div>
</div>
<div ui-view class="col-xs-12">
<div class="row">
<div class="col-xs-12" ng-if="vm.isTabOneSelected">
<div ng-include src="'components/Cards/Tabs/TabOne/TabOne.html'"></div>
</div>
</div>
<div class="row">
<div class="col-xs-12" ng-if="vm.isTabTwoSelected">
<div ng-include src="'components/Cards/Tabs/TabTwo/TabTwo.html'"></div>
</div>
</div>
<div class="row">
<div class="col-xs-12" ng-if="vm.isTabThreeSelected">
<graph-panel panel-title="TabThree {{vm.isTabThreeSelected}}" chart-config="vm.charts.TabOneChartSite"></graph-panel>
</div>
</div>
</div>
On Each Controller, You can cache your loaded data in a service, and when you load your controller you will start by checking this service if it does not have the data, then you will request it from your APIs , in this case you only request your data once you access the tab for the first time :
eg. your service
app.service('dataService', function() {
this.firstTabData = null;
this.getFirstTabData = function () {
return this.firstTabData;
};
this.setFirstTabData = function (data) {
this.firstTabData = data;
};
});
your controller
app.controller('tabOne', function($scope, dataService) {
$scope.data = {};
$scope.load = function () {
if(dataService.getFirstTabData()) {
$scope.data = dataService.getFirstTabData();
}
else {
$scope.data = getDataFromAPI();
}
};
var getDataFromAPI = function () {
//get your data
dataService.setFirstTabData(dataFromAPI);
};
});
Related
I have the following angular code for showing student info in the tabbed format.
Following is the student.html class
<div class="panel panel-default">
<ul class="nav nav-tabs">
<li ng-repeat="studentTab in studentList"
ng-class="{active: selectedStudentTab.name === studentTab.name}">
<a ng-click="selectStudentTab(studentTab)">{{studentTab.name}}</a>
</li>
</ul>
<div class="panel-body">
<div class="tab-content">
<div class="tab-pane active" ng-repeat="studentTab in studentList"
ng-show="selectedStudentTab.name === studentTab.name">
<div style="padding: 35px; text-align: left;">
<div ng-repeat="project in studentTab.projects">
<p><pre>{{project.log}}</pre></p>
</div>
</div>
</div>
</div>
</div>
</div>
in my studentController.js I have assigned the oth element of studentList to the tab, following is the code:
$scope.init = function () {
$rootScope.initOrRedirectToLandingPage($scope.loadStudents);
};
$scope.studentList = [];
$rootScope.loadStudents = function(){...
};
$scope.selectedStudentTab = $scope.studentList[0];
$scope.selectStudentTab = function (studentTab) {
$scope.selectedStudentTab = studentTab;
};
Here the tabs are created properly, but the first tab is not selected/active by default on loading of the page and becomes active only on the click event.
Can someone help me to figure out what am I missing? any help is appreciated.
In your controller after you load the studentList assign the selectedStudentTab to the first item in the list.
$scope.studentList = [...];
$scope.selectedStudentTab = $scope.studentList[0];
I have a little problem with LightGallery plugin (lightGallery - Git). I use jQueryMobile.
My gallery is on a specific page. When I arrive on this page, it will request a remote server to get some pics.
Then I initialize LightGallery. No problem the first time.
But when I leave the Gallery Page and come back after (there is a new request to server), lightGallery is not running.
No error in the browser, I have my photos displayed but I can't click on it to run LightGallery like I've done the first time.
My Code:
HTML:
<div data-role="page" id="pageGallery" data-theme="a">
<div data-role="content" class="center-body">
<h3 class="nomGroupe"></h3><br/>
<div class="demo-gallery">
<ul id="lightgallery" class="list-unstyled row">
</ul>
</div>
</div>
</div>
Javscript :
$( document ).on( "pagecontainerbeforeshow", function ( event, ui ) {
var activePage = $.mobile.pageContainer.pagecontainer( "getActivePage" );
if (activePage[0].id == "pageGallery" ) {
$('#lightgallery').empty();
$(".groupName").empty().append("group "+localStorage['groupName']);
envoieRequete('http://myServer/', {'idGroup' : localStorage['idGroup'], 'token' : localStorage['token']}, 'post', function(output){
if(output.group.photos.length === 0) {
$("#lightgallery").append('<br/><p>Empty for Group : ' + localStorage['groupName']+'</p>');
}
else {
for(i=0; i<output.group.photos.length; i++) {
$('#lightgallery').append('<li class="col-xs-6 col-sm-4 col-md-3" data-responsive="http://myServer/'+localStorage['token']+'/'+localStorage['idGroup']+'/' + output.group.photos[i].id
+ '" data-src="http://myServer/'+localStorage['token']+'/'+localStorage['idGroup']+'/' + output.group.photos[i].id + '" data-sub-html="<h4>PhotoAlt</H4>"><a href=""><img class="img-responsive"\n\
src="http://myServer/'+localStorage['token']+'/'+localStorage['idGroup']+'/' + output.group.photos[i].id + '"/></a></li>');
}
}
});
}
});
$(document).on("pagecontainershow", function () {
var activePage = $.mobile.pageContainer.pagecontainer("getActivePage");
var activePageId = activePage[0].id;
switch (activePageId) {
case 'pageGallery':
$(document).on("tap", "#lightgallery li", function (){
$('#lightgallery').lightGallery({});
});
}
});
You might be using wrong html markup. you can check the following code for reference. This is sample code.
HTML
<div class="row">
<div class="large-12 columns">
<ul class="small-block-grid-2 medium-block-grid-3" id="lightgallery">
<li> <a class="item" href="img/alchemy_icon1.jpg"><img src="img/alchemy_icon1_th.jpg"></a>
</li>
<li> <a class="item" href="img/chandra1.jpg"><img src="img/chandra1-th.jpg"></a>
</li>
<li> <a class="item" href="img/Fish.jpg"><img src="img/Fish-th.jpg"></a>
</li>
</ul>
</div>
</div>
Javascript
$("#lightgallery").lightGallery({
selector: '.item'
});
my controller :
.controller('BlogController', function(blogFactory, $routeParams, $scope){
var that=this;
stat=false;
this.checkbookmark = function(bId){
console.log(bId)
blogFactory.checkBookmark(bId, function(response){
console.log(response)
if(response == "bookmarked"){
that.stat = true;
}
else{
that.stat = false;
}
})
}
my html code :
<div class="container" ng-controller="BlogController as blogCtrl">
<div class="row" ng-repeat="chunk in blogCtrl.blogs | filter: filter_name | orderBy:'-created_at' | groupBy: 3">
<div class="outerbox1 col-sm-4" ng-repeat="blog in chunk" >
<div class="innerbox3" ng-init="blogCtrl.checkbookmark(blog._id)">
<br>
<div> > READ MORE
<a ng-if="blogCtrl.stat" ng-href="#" ng-click="blogCtrl.removebookmark(blog._id)" class="glyphicon glyphicon-heart pull-right">{{blogCtrl.stat}}</a>
<a ng-if="!blogCtrl.stat" ng-href="#" ng-click="blogCtrl.addbookmark(blog._id)" class="glyphicon glyphicon-heart-empty pull-right">{{blogCtrl.stat}}</a>
</div>
</div>
</div>
</div>
</div>
service factory :
factory.checkBookmark = function(info, callback){
$http({
url:'api/check_bookmark_blog',
method:'POST',
headers:{'x-access-token': token},
params:{'user_id': userid},
data:{'blog_id':info}
}).success(function(data){
console.log(data);
callback(data)
})
}
I want to show glyphicon based on the value of stat
I have 6 blogs, first 3 are bookmarked and next 3 are not.
The problem i'm getting is that the stat value is always set according to the last bookmark and hence it is always false / true (based on the condition of last blog).
How to resolve this issue and set glyphicon respective to value of stat for each blog?
So there are multiple ways of implementing it.
You can either store the true/false values in either an array or you can run a function every time which returns true/false.
Using function which returns true/false values:
Modify your checkbookmark function to return true/false values as follows,
Controller code:
.controller('BlogController', function (blogFactory, $routeParams, $scope) {
this.checkbookmark = function (bId) {
blogFactory.checkBookmark(bId, function (response) {
if(response == "bookmarked"){
return true; // returns true if bookmarked
} else {
return false; // returns false if not bookmarked
}
});
};
});
HTML code:
<div class="container" ng-controller="BlogController as blogCtrl">
<div class="row" ng-repeat="chunk in blogCtrl.blogs | filter: filter_name | orderBy:'-created_at' | groupBy: 3 track by $index">
<div class="outerbox1 col-sm-4" ng-repeat="blog in chunk track by $index" >
<!-- removed ng-init here -->
<div class="innerbox3">
<br>
<div> > READ MORE
<a ng-if="blogCtrl.checkbookmark(blog._id)" ng-href="#" ng-click="blogCtrl.removebookmark(blog._id)" class="glyphicon glyphicon-heart pull-right">{{blogCtrl.stat}}</a>
<a ng-if="!blogCtrl.checkbookmark(blog._id)" ng-href="#" ng-click="blogCtrl.addbookmark(blog._id)" class="glyphicon glyphicon-heart-empty pull-right">{{blogCtrl.stat}}</a>
</div>
</div>
</div>
</div>
</div>
Using an array:
Store the true/false values in an array and access them in html using
track by $index in your ng-repeat clause.
Controller code:
.controller('BlogController', function (blogFactory, $routeParams, $scope) {
this.stat = []; // initializing array
this.checkbookmark = function (bId) {
blogFactory.checkBookmark(bId, function (response) {
if(response == "bookmarked"){
this.stat.push(true);
} else {
this.stat.push(false);
}
});
};
});
HTML code:
<div class="container" ng-controller="BlogController as blogCtrl">
<div class="row" ng-repeat="chunk in blogCtrl.blogs | filter: filter_name | orderBy:'-created_at' | groupBy: 3 track by $index">
<!-- note the usage of track by $index in ng-repeat -->
<div class="outerbox1 col-sm-4" ng-repeat="blog in chunk track by $index" >
<div class="innerbox3" ng-init="blogCtrl.checkbookmark(blog._id)">
<br>
<div> > READ MORE
<a ng-if="blogCtrl.stat[$index]" ng-href="#" ng-click="blogCtrl.removebookmark(blog._id)" class="glyphicon glyphicon-heart pull-right">{{blogCtrl.stat}}</a>
<a ng-if="!blogCtrl.stat[$index]" ng-href="#" ng-click="blogCtrl.addbookmark(blog._id)" class="glyphicon glyphicon-heart-empty pull-right">{{blogCtrl.stat}}</a>
</div>
</div>
</div>
</div>
</div>
Hope this solves the problem.
I exactly don't know which implementation is better or any other implementations for the same. May be other folks in stackoverflow could suggest.
controller:
.controller('BlogController', function(blogFactory, $routeParams, $scope){
var that=this;
stat=false;
this.checkbookmark = function(bId){
console.log(bId)
blogFactory.checkBookmark(bId, function(response){
console.log(response)
if(response == "bookmarked"){
that.stat = true;
}
else{
that.stat = false;
}
})
}
html code:
<div class="container" ng-controller="BlogController as blogCtrl">
<div class="row" ng-repeat="chunk in blogCtrl.blogs | filter: filter_name | orderBy:'-created_at' | groupBy: 3">
<div class="outerbox1 col-sm-4" ng-repeat="blog in chunk" >
<div class="innerbox3" ng-init="blogCtrl.checkbookmark(blog._id)">
<br>
<div> > READ MORE
<a ng-if="blogCtrl.stat" ng-href="#" ng-click="blogCtrl.removebookmark(blog._id)" class="glyphicon glyphicon-heart pull-right">{{blogCtrl.stat}}</a>
<a ng-if="!blogCtrl.stat" ng-href="#" ng-click="blogCtrl.addbookmark(blog._id)" class="glyphicon glyphicon-heart-empty pull-right">{{blogCtrl.stat}}</a>
</div>
</div>
</div>
</div>
</div>
I want to show glyphicon based on the value of stat
I have 6 blogs, first 3 are bookmarked and next 3 are not.
The problem i'm getting is that the stat value is always set according to the last bookmark and hence it is always false / true (based on the condition of last blog).
How to resolve this?
Instead of setting the stat property on the controller you should set the property on the blog object (it obviously belongs to the object)
Replace your checkbookmark function with this:
this.checkbookmark = function(blog){ //pass the entire blog, not just the id
blogFactory.checkBookmark(blog._id, function(response){
console.log(response)
if(response == "bookmarked"){
blog.stat = true; //set the property on blog instead of the controller
}
else{
blog.stat = false;
}
})
}
And then use it like this:
<div class="innerbox3" ng-init="blogCtrl.checkbookmark(blog)">
<br>
<div> > READ MORE
<a ng-if="blog.stat" ng-href="#" ng-click="blogCtrl.removebookmark(blog._id)" class="glyphicon glyphicon-heart pull-right">{{blog.stat}}</a>
<a ng-if="!blog.stat" ng-href="#" ng-click="blogCtrl.addbookmark(blog._id)" class="glyphicon glyphicon-heart-empty pull-right">{{blog.stat}}</a>
</div>
</div>
You will need to make similar changed to your add and removebookmark functions
My code is simple. I need to refresh a ng-repeat.
HTML
<div class="quick-actions" ng-controller="DashboardController">
<div class="ui accordion segment">
<div class="ui top attached label active title">
<?php echo __('My Tasks'); ?>
<i class="minus icon"></i>
</div>
<div class="active content">
<div class="ui items" ng-show="myTasks" id="myTasks">
<!-- Creacion de Items de los Taks -->
<div class="item" ng-repeat="T in myTasks">
<div class="content">
<a class="header" href="/angular/#/task/{{ T.Task.id }}">
{{ T.Task.name }}
</a>
<div class="meta">
{{ T.Task.due_date | date : 'dd-MMM-yyyy' }}
</div>
<div class="extra high-priority" ng-if="T.Task.priority == 50">
<i class="circle icon"></i>
<?php echo __('High'); ?>
</div>
<div class="extra medium-priority" ng-if="T.Task.priority == 25">
<i class="circle icon"></i>
<?php echo __('Medium'); ?>
</div>
<div class="extra low-priority" ng-if="T.Task.priority == 0">
<i class="circle icon"></i>
<?php echo __('Low'); ?>
</div>
</div>
</div>
<!-- Termina Creacion de los Items -->
</div>
</div>
</div>
</div>
When income is well DashboardController in angularjs load ng-repeat. Data is correct here.
.controller('DashboardController', function ($scope, $state, $rootScope, $stateParams, $q, $timeout, $http, $sce, $location, Sesion, Dashboard, Fullscreen) {
Dashboard.get_all_tasks().then(function (response) {
$scope.myTasks = response;
});
})
What I need is that when I'm in another controller I can update this ng-repeat. It does not work (data incorrect) here.
.controller('NewTaskController', function ($scope, $state, $rootScope, $stateParams, $q, $timeout, $http, $sce, Sesion, Users, Opportunities, Dashboard) {
Dashboard.get_all_tasks().then(function (response) {
$timeout(function () {
$scope.$apply(function () {
$scope.myTasks = response;
});
});
});
})
Any idea what I'm doing wrong?
You need to implement a service to pass data between controllers. Here is a simplified example. It is in this plunkr here to play with.
var projectModule = angular.module('project',[]);
projectModule.factory('Service', function() {
return {
thing : {
x : 100
}
};
});
function FirstCtrl($scope, Service) {
$scope.thing = Service.thing;
$scope.name = "First Controller";
}
function SecondCtrl($scope, Service) {
$scope.foo = Service.thing;
$scope.name = "Second Controller!";
}
In this way $scope.thing from the first controller is linked to scope.foo in the second controller via the service using thing
You will need to define the structure of myTasks in the service you define so that all the elements gets passed correctly.
Try implementing this into your project and if you have a specific hangup comment here and we will help but I don't know all your code or structure of myTasks so I'm not giving copy/paste code.