Skip to content Skip to sidebar Skip to footer

How To Generate Properties Of Array With Some Default Value While Doing Ng Repeat?

Below is my array : $scope.parent.cars1 = ['Saab', 'BMW']; // There are more than 1000 records in this array $scope.child.Cars1 = []; Now I am trying to assign $scope.parent.cars

Solution 1:

I've update and cleanup my PLUNKER with a real 8000 records... I have to say that if you don't use pagination o some technique that only write a certain quantity of records in the DOM, you probably have a bad perfomance. As a advice to improve better perfomace:

  • Try to do much work as you can in local vars before of binding the array
  • Work with a local copy of the whole array and only bind a limit quantity of records in the screen. (Use javascript slice(start, end))
  • add track by $index (angular docs ng-repeat)
  • When you are using angular 1.3+, disable two-way data binding if isn't necessary (angularJs one-way data binding)

My code:

CONTROLLER JS:

var bigArray = ["Dandai", "Immātīn", "Oefatu" ...];
var itemsLocal = []; //Local copy of the items to workvar PAGE_SIZE = 250;
var TOTAL_RECORDS = bigArray.length;

var start = 0;
var end = PAGE_SIZE;

$scope.items = []; //Items to repeat in screen$scope.loadData = loadData;
$scope.prevPage = prevPage;
$scope.nextPage = nextPage;

transformData();
loadData();

functiontransformData() {
    for (var i = 0; i < TOTAL_RECORDS; i++) {
      itemsLocal.push({
        name: bigArray[i],
        selected: true,
        operation: 1
      });
    }
}

functionloadData() {
    $scope.items = itemsLocal.slice(start, end); //repeat only certain part of the data
}

functionprevPage() {
    if (start < PAGE_SIZE) 
        return;

    start = start - PAGE_SIZE;
    end = end - PAGE_SIZE;
    loadData();
}


functionnextPage() {
    if (end >= TOTAL_RECORDS) 
        return;

    start = start + PAGE_SIZE;
    end = end + PAGE_SIZE;
    loadData();
}

HTML:

<div><buttontype="button"ng-click="prevPage()">Load Previous</button><buttontype="button"ng-click="nextPage()">Load Next</button></div><hr/><tableclass="table"><thead><tr><th>Column 1</th><th>Column 2</th></tr></thead><tbody><trng-repeat="item in items track by $index"><td><inputng-model="item.selected"type="checkbox"> {{ item.name }}
        </td><td><div><inputtype="radio"class="radio-custom"ng-model="item.operation"value="0">Clear
          </div><div><inputtype="radio"class="radio-custom"ng-model="item.operation"value="1">Clear and Save
          </div></td></tr></tbody></table>

Solution 2:

You can use Array.map() method to iterate the array.

For my own testing i created the array($scope.array1000) with 1000 records and it is loaded fine without any issues(hang,more load time,etc..).

DEMO

var app = angular.module('myApp', []);

app.controller('MyCtrl',function($scope) {
  $scope.parent = { "cars1": ["Saab", "BMW"] };
  $scope.array1000 = [];
  for (var i=0; i< 1000; i++) {
    $scope.array1000.push($scope.parent.cars1[0]+''+i);
  }
  
  var res = $scope.array1000.map(function(record) {
    return {
      "name": record,
      "operation": 1,
      "selected": true
    }
  });
  
  console.log(res);
});
<scriptsrc="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script><divng-app="myApp"ng-controller="MyCtrl"><divng-repeat="item in array1000">
    {{ item }}
  </div></div>

Solution 3:

your problem is not the data initializing that making the browser too slowly,the main problem is manipulate DOM element with a huge of data in a single thread,then the browser look like hanged up。so you must render a piece of data from the huge of the data at a time.you can use the interval service $interval,because I never used angularjs,this problem spent me most of the night,but I think it's worth to do.

// Instantiate the app, the 'myApp' parameter must// match what is in ng-appvar myApp = angular.module('myApp', []);
functiontimeFormat(time) {
    var units = ['ms', 's', 'm'];
    var radix = [1000, 60, 60];

    for (var i = 0; i < units.length; i++) {
        if (time < radix[i]) {
            return time.toFixed(2) + units[i];
        }
        time /= radix[i];
    }
    return time + 'h';
}
functionrun(name, fn) {
    var start = +newDate;
    var result = fn.call(this);

    functiontimeElapsed() {
        var elapsed = +newDate - start;
        console.log(['Stage[' + name + ']', 'elapsed', timeFormat(elapsed)].join(' '));
    }

    if (typeof result.then == 'function') {
        result.then(timeElapsed);
    } else {
        timeElapsed();
    }
    return result;
}
myApp.controller('ToddlerCtrl', function ($scope, $timeout, $interval) {
    var cars = run('initializing data', function () {
        varDATA_SIZE=1000;
        var cars = [];
        for (var i = 0; i < DATA_SIZE; i++) {
            cars.push(i);
        }
        return cars.map(function (_, i) {
            return'car-' + i;
        }).map(function (name) {
            return {
                name: name,
                operation: 1,
                selected: true
            };
        });
    });
    $scope.className = 'loading';
    //initialing cars for rendering
    $scope.cars = [];
    varBATCH_SIZE = 30;
    var batches = Math.floor(cars.length / BATCH_SIZE);
    varDELAY = 1;
    var push = Array.prototype.push;


    var task = run('filling data', function () {
        functionfill() {
            push.apply($scope.cars, cars.splice(0, BATCH_SIZE));
            //rendering data into browserconsole.log('Remaining ' + cars.length + ' items ...');
        }

        fill();
        return $interval(fill, DELAY, batches);
    }).then(function () {
        $scope.className = 'hidden';
    });

});
ul, li, html, body { margin: 0; padding: 0; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } ul { list-style: none; } .loading { font-size: 2em; font-weight: bold; position: fixed; right: 20px; top: 20px; color: green; } .hidden { display: none; } .loadingem { position: relative; display: inline-block; height: 1em; width: 50px; } .loadingspan { position: absolute; text-overflow: clip; -webkit-animation: loading 1s infinite linear; -o-animation: loading 1s infinite linear; animation: loading 1s infinite linear; } @keyframes loading { from { clip: rect(0, 0, 50px, 0); } to { clip: rect(0, 50px, 50px, 0); } } @-o-keyframes loading { from { clip: rect(0, 0, 50px, 0); } to { clip: rect(0, 50px, 50px, 0); } } @-webkit-keyframes loading { from { clip: rect(0, 0, 50px, 0); } to { clip: rect(0, 50px, 50px, 0); } } .loading:first-letter { font-size: 1.5em; } li { float: left; width: 21%; border: 2px solid #eee; margin: 10px2%; padding: 5px; } .car { padding: 5px010px; display: block; } .button-group { text-align: right; }
<scriptsrc="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js"></script><mainng-app="myApp"><divng-controller="ToddlerCtrl"><divng-class="className"class="loading">Loading <em><span>...</span></em></div><ul><ling-repeat="item in cars"><labelclass="car"><inputng-model="table.selected"type="checkbox"name="a{{$index}}"id="a{{$index}}">{{ item.name }}
                 </label><divclass="button-group"><label><inputtype="radio"ng-model="item.operation"value="0"name="b{{$index }}"id="b{{$index}}">
                         Clear
                     </label><label><inputtype="radio"ng-model="item.operation"value="1"name="b{{$index }}"id="c{{$index}}">
                         Clear and Save
                     </label></div></li></ul></div></main>

Solution 4:

something like .. ?? .. hope it helps

$scope.child = {};
  if ($scope.child.Cars1 == undefined)
            $scope.child.Cars1 = [];
        var all = angular.copy($scope.parent.Cars1);
        var test = [];

  angular.forEach(all, function (obj, key) {
             test.push(
           {
               name: obj,
               operation: 1, // this value is used to tick all radio button of clear and save
               selected: true// this value is used to check all checkbox to true by default
           }
       );

$scope.child.Cars1 = test;
        })

So you don't work with $scope vars (cause are haeavy and freeze UI) ...

Solution 5:

Well, the plunker had a lot of errors. I am assuming you created it in a haste to showcase the sample code.

Without actually seeing your actual files with actual data, it is really hard to pin-point the problem.

Try to use a simple array.map() function. Check this out http://plnkr.co/edit/Sx3lMIBEMMj4xrOBI5vI?p=preview

A mapping function on your array that returns an object will arrange the data in the required form.

If the hanging is due to js bottlenecks, it might resolve it. Otherwise, try a simple for loop which iterates over the array. A for loop is the fastest and most efficient way to loop through an array as there is not overhead of a function call.

However, more than 1000 DOM elements themselves can cause the browser to hang. If my plunker doest help, try to show only a portion of the complete data at a time.

This can be accomplished through simple pagination, in which only a page with specific number of entries is shown at a time.

Or you can use directives like virtual repeat.

Even infinite-scroll way of buffering the DOM.

Totally depends upon the use case.

Post a Comment for "How To Generate Properties Of Array With Some Default Value While Doing Ng Repeat?"