How to make Vuetify v-for render faster - html

Hello i am new in vuejs and vuetify, i am now want to display item about 400colums and 6 rows, colum_id (cid) and row_id(rid) but render speed is slow sorry may i know how to improve this loop performance Thank before hand :
<v-layout>
<div class="reglahan-table-result-betting">
<tr
v-for="i in 6"
:key="i">
<td
v-for="j in 60"
:key="j">
<div
v-for="(item, k) in props.resultBetting"
:key="k">
<span
v-if="Number(item.cid) === j && Number(item.rid) === i"
:class="item.color"
/>
</div>
<span class="no-circle" />
</td>
</tr>
</div>
</v-layout>

Of course you can optimize that. The problem is that in your most inner loop, you loop on every element of the array. You shouldn't do that.
First you need to properly index your table, I would create a 'computed' function as such :
computed: {
indexedResultBetting: function () {
let ret = {}
self.props.resultBetting.forEach(function(item, index){
if(!item.rid in ret)
ret[item.rid] = {}
ret[item.rid][item.cid] = item.color
})
return ret
}
}
Then you can simply show that with something like :
<v-layout>
<div class="reglahan-table-result-betting">
<tr
v-for="i in Object.keys(indexedResultBetting)"
:key="i">
<td
v-for="j in Object.keys(indexedResultBetting[i])"
:key="j">
<div
<span
:class="indexedResultBetting[i][j]"
/>
</div>
<span class="no-circle" />
</td>
</tr>
</div>
</v-layout>
I haven't tested it, there is certainly some tinkering to do.

Related

applying pagination to a table in angular js where map is what i'm iterating through in ng-repeat

i'm iterating through map where key and value pair is there and i'm not getting how to apply pagination of those data where that map data is generated from the database directly.i'm iterating through map where key and value pair is there and i'm not getting how to apply pagination of those data where that map data is generated from the database directly.
<table>
<thead></thead>
<tbody>
<tr>
<td><marquee>
<h3>
A tag is a keyword or label that categorizes your question with
other, similar questions. Using the right tags makes it easier
for others to find and answer your question.
</h4>
</marquee>
<hr></td>
</tr>
<tr ng-repeat="(key,value) in tagForm.data track by $index">
<td align="left">
<div ng-init='tagForm.getTag(key)'
class=" w3-container w3-card w3-white w3-margin w3-round "
style="padding-left: 40px; padding-right: 40px;">
<br>
<p ng-repeat="data2 in tagForm.message track by $index">
<a ng-click="tagForm.getAnswer(key)">Q. {{value}}</a> <span
class="badge">{{data2}}</span> <br>
</p>
<ul ng-repeat="(key2,value2) in tagForm.ans track by $index">
<li><b ng-if="key==key2">Ans. {{value2}}</b></li>
</ul>
<div ng-init='tagForm.getUser(key)'>
<b>Posted
by:{{tagForm.user2[$index]}}</b>
</div>
<button class="btn btn-default" id="{{$index}}"
ng-click="count1=count1+1" ng-init="count1=5+($index*3)-5">
Upvote <span class="badge">{{count1}}</span>
</button>
<button class="btn btn-default" id="{{$index}}"
ng-click="count=count+1" ng-init="count=1+($index*2)">
Downvote<span class="badge">{{count}}</span>
</button>
<button class="btn btn-default" ng-click="gotoanswer()">Answer
this question</button>
<br> <br />
</div> <br>
</td>
<td height=100px><br /></td>
</tr>
</tbody>
</table>
use the following pagination in your html file
<uib-pagination ng-show="isPaginate == false "
total-items="totalItems" ng-model="currentPage"
boundary-links="true" items-per-page="numPerPage"
class="pagination-sm" ng-change="pageChanged()" max-size="5">
</uib-pagination>
and then initialize the variable as per requirement in angular controller
$scope.totalItems = 80;//length of records
$scope.currentPage = 1;
$scope.numPerPage = 10;
var startpos = 0;
for dynamically loading records (loading records batch wise instead of loading all at time) refer following function
$scope.pageChanged = function() {
// if($scope.currentPage!=1)
$scope.isCollapsed = false;
$scope.isRCollapsed = false;
$scope.page = ($scope.currentPage - 1) * $scope.numPerPage;
callApi($scope.page);//get next set of 10 records
console.log('Page changed to: ' + $scope.currentPage);
};

Angularjs use one controler in two views, scope is not loading

I have an e-commerce page. I want when the user deletes a product from the shopping cart to reload the specific divs. I have the index page that contains
a div with an ng-repeat with my products, and in the index I have an content view with the same ng-repeat. I want when for example I delete a
product, to update the these ng-repeat. I tried, the $rootscope.$digest; and $scope.$apply(); but there are not working. Below, you can see my code.
My index page
<div ng-controller="ShoppingCartCtrl">
<div data-toggle="dropdown"> </div>
<ul>
<li ng-repeat="item in resultShoppingCart">
<a title="Product Title Here" ui-sref="single_product({id:item.productId})"></a>
<div class="product-details">
<div class="access"><a title="Remove This Item" ng-click="delete(userId,item.productId)">Remove</a> <a class="btn-edit" title="Edit item" ui-sref="shoppingCart"><i class="icon-pencil"></i><span class="hidden">Edit item</span></a> </div>
<p class="product-name"><a ui-sref="single_product({id:item.productId})" ng-bind="item.productName"></a> </p>
<strong ng-bind="item.quantity"></strong> x <span class="price" ng-bind="item.unitPrice"></span>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="actions">
<a ui-sref="shoppingCart"><span>View Cart</span></a>
</div>
<div id="wrap">
<!-- Content -->
<div class="container">
<div ui-view=""></div>
</div>
</div>
My shopping cart page
<tbody>
<tr ng-repeat="item in resultShoppingCart track by $index">
<td class="cart_product"><a ui-sref="single_product({id:item.productId})"></a></td>
<td class="cart_description">
<p class="product-name" ng-bind="item.productName"></p>
</td>
<td class="price" ng-bind="item.unitPrice"><span></span></td>
<td class="qty">
<input class="form-control input-sm" type="text" ng-value="item.quantity" ng-model="item.quantity">
<i class="fa fa-plus" ng-click="changeQuantity(item, 1)"></i> <i class="fa fa-minus" ng-click="changeQuantity(item, -1)"></i>
</td>
<td class="price" ng-bind="item.price"><span></span></td>
<td class="action"><a ng-click="delete(userId,item.productId)">Delete item</a></td>
</tr>
</tbody>
And my shopping cart controller:
$scope.delete = function (userId, productId) {
var jsonDelete = '...';
dataProvider.delete(jsonDelete).then(function (response) {
//$scope.$digest(); //not working
//$scope.$apply();//not working
});
$state.reload();
//$scope.$digest;//not working
//$scope.$apply();//not working
};
With the state.reload I can reload my shopping cart page. Can anyone help me?
Few modifications will make it work.
Pass $index to your delete function, like,
ng-click="delete(userId,item.productId, $index)"
Then inside your delete handler, you can use splice to delete the object from your existing array. Like
$scope.delete = function (userId, productId, index) {
var jsonDelete = '...';
dataProvider.delete(jsonDelete).then(function (response) {
$scope.resultShoppingCart.splice(index, 1);
});
$state.reload();
};
Edit:
Use events to update the parent value. Like,
In shopping cart
$scope.delete = function (userId, productId, index) {
var jsonDelete = '...';
dataProvider.delete(jsonDelete).then(function (response) {
$scope.resultShoppingCart.splice(index, 1);
$rootScope.$emit('updateList',productId);//Passing productid instead of index is safer as it is not necessary to stick to the order of array.
});
$state.reload();
};
In index page
Catch the event which is triggered after deleting.
$rootScope.$on('updateList', function (productId) {
for (let i = 0; i < $scope.resultShoppingCart.length ; i++) {
if ($scope.resultShoppingCart[i].productId == productId) {
$scope.resultShoppingCart.splice(i, 1);
break;
}
}
});

ng-repeat not compiling directive inside table row

I have this table that when you click on the table row this gets "expanded"(it actually slide another table row with the table's colspan), for this I built this angular directive
app.directive('dirt', function($compile){
return{
restrict:'A',
scope:{
},
replace: true,
compile:function(element, attrs){
element.next().children().children().hide();
element.next().children().hide();
var table = element.parent().parent();
var colspan = table.find('tr:first > th').length;
console.log(table.find('tr'))
if(!attrs['compiled']){
var tr = element.next();
tr.children().attr('colspan', colspan);
$compile(tr.children());
}
element.bind('click', function(){
event.stopPropagation();
element.next().children().slideToggle();
element.next().children().children().slideToggle();
});
}
}
});
it's called dirt, and you put it in the tr which you need to click to expand the next tr
something like this
<tbody>
<tr dirt>
<td>123465</td>
<td>A123</td>
<td>7455</td>
<td>MX</td>
<td>US</td>
<td>2</td>
<td>75000</td>
<td>7500</td>
<td>784</td>
</tr>
<tr>
<td>
<div style="width:100%;min-height:1px;background-color:yellow;float:left;">
<div class="col-xs-6">
<span style="font-size:60px;">A4</span>
</div>
<div class="col-xs-6">
<span>rklgjnrkelgtjnkelrtm;lremt;lermt;lremt;lermt</span>
<br />
rlgtjknrekltrmnekltmret;reltmklertmnkelrt
<br />
klgmkldgmnjklfdngmkldfng,mdfgn,dfmgndf,g
</div>
</div>
</td>
</tr>
</tbody>
I have this The way is needed to show how this works with only one set of tr, you just need to click on the first table row to expand it
The problem here is that when I try to use ng-repeat-start and end this happens
plunkr failed
I don't know how to compiled the second row affected by the dirt directive so it can be recognized for the ng-repeat dir, hope you know something about
thanks.

Angular Ng-If Ng-Style not changing the table font colour

I have the following code which is an ionic list which populates the data retrieved. Im trying to colour code it into different colours based on the Status reponse.
<ion-list>
<ion-item ng-repeat="test in tests" class ="item-text-wrap" style="height:40%">
<a href="#/tab/test/test-detail/{{test.ID}}">
<div style="width:80%; float:left;">
<table>
<span ng-if="test.Status == 'Cleared'" ng-style="color:green">
<tr>
<td> <strong>Remark: </strong></td>
<td style="padding:3px">{{test.Remark}}</td>
</tr>
<tr>
<td><strong>Status:</strong></td>
<td style="padding:3px">{{test.Status}}</td>
</tr>
</span>
</table>
</div>
</ion-item>
</ion-list>
But the colour of the table data still does not change. What could be the problem? Am i using the ng-if and ng-style wrongly? Thanks!
Update 1: Using the insights provided by #SSH, i updated my controller with the following codes:
Html:
<ion-list>
<ion-item ng-repeat="test in tests" class ="item-text-wrap" style="height:40%">
<a href="#/tab/test/test-detail/{{test.ID}}">
<div style="width:80%; float:left;">
<table>
<span ng-style="calculateStyle()">
<tr>
<td> <strong>Remark: </strong></td>
<td style="padding:3px">{{test.Remark}}</td>
</tr>
<tr>
<td><strong>Status:</strong></td>
<td style="padding:3px">{{test.Status}}</td>
</tr>
</span>
</table>
</div>
</ion-item>
</ion-list>
Controller:
$scope.calculateStyle = function() {
var style={}
console.log('test3: '+$scope.tests.Status);
console.log('test6: '+$scope.Status);
if ($scope.Status == 'Cleared') {
style.color='green';
console.log('Viola');
}
else{
console.log('GG');
}
return style;
}
})
But the result returned in the controllers are still null/undefined. test3 and test6 returned me 'undefined' while the If statement returned me 'GG'. What could be the problem? Thanks!
Update 2: Using SSH answers, i modified to the following:
Html:
<span ng-style="calculateStyle(test)">
Controller:
$scope.calculateStyle = function(test) {
var style={}
if (test.Status == 'Cleared') style.color='green';
return style;
}
But the test variable at the controller is still undefined. Using $scope.test doesn't work too. What could be the problem?
Yes you do use it wrongly. You need to pass an object consisting of style names and conditions:
<span ng-style="{color:(test.Status == 'Cleared')?'green'}">
or better use a function in your controller to calculate and return style object, to keep your template clean:
<span ng-style="calculateStyle(test)">
and then in your controller definition
$scope.calculateStyle = function(test) {
var style={}
if (test.Status == 'Cleared') style.color='green';
return style;
}

AngularJS - ng-repeat to display empty cell/s when data is not available

I have a simple ng-repeat that loops through a JSON file with a list of countries and details about that country e.g. currency, population for a particular set of months (24 in this case)
My ng-repeat loops through the first 12 months successfully, and displaying the corresponding text when the ng-switch criteria is met.
The issue i am facing, is that for some countries, we there is less than 12months worth of data, in some cases, only 3 months.
What i am struggling to do, is that if there is not sufficient data available, to display an empty cell.
Here's my ng-repeat:
<tr ng-repeat="country in Countries[key]">
<th>{{country.countryName}}</th>
<td ng-repeat="countryDetails in country.Details.slice(0, 12)" ng-switch="countryDetails.Population">
<span ng-switch-when="10000">Medium</span>
<span ng-switch-when="20000">Large</span>
<span ng-switch-when="30000">Larger</span>
<span ng-switch-when="40000">Very Large</span>
<span ng-switch-default>Error</span>
</td>
</tr>
Thanks
I created a fiddle similar to your case and fixed it like this:
<td ng-repeat="countryDetails in country.Details.slice(0, 12)"
ng-switch="countryDetails">
<span ng-switch-when="11">Medium</span>
<span ng-switch-when="22">Large</span>
<span ng-switch-when="33">Larger</span>
<span ng-switch-when="44">Very Large</span>
<span ng-switch-default>Error</span>
</td>
<td ng-repeat="emptyCell in getEmptyCells(country.Details.length)">
empty
</td>
JS
$scope.getEmptyCells = function(len){
var emptyCells = [];
for(var i = 0; i < 12 - len; i++){
emptyCells.push(i);
}
return emptyCells;
}
Fiddle
You can create a custom range in your scope:
$scope.range = function(n) {
return new Array(n);
};
And then loop with it on your country.Details array
<td ng-repeat="a in range(12) track by $index" ng-switch="country.Details[ $index ].Population">
<span ng-switch-when="10000">Medium</span>
<span ng-switch-when="20000">Large</span>
<span ng-switch-when="30000">Larger</span>
<span ng-switch-when="40000">Very Large</span>
<span ng-switch-default>Error</span>
</td>
Hi here is a fiddle which may help you Fiddle
<tr ng-repeat="details in countries.Details">
<td ng-repeat="detail in details">{{detail}}</td>
<td ng-if="details.length<12" ng-repeat="empty in getTempArray(details.length) track by $index">{{empty}}</td>
</tr>
I am not sure if I understood correctly, but I had some problems while using ng-repeat. If your array may have duplicate values then you should track by $index.
Try writing inside ng-repeat countryDetails in country.Details.slice(0, 12) track by $index instead of countryDetails in country.Details.slice(0, 12)