কীভাবে একটি বিশাল ডেটাসেট (কৌণিক.জেএস) এর উপরে এনজিআরপিটেনের কর্মক্ষমতা উন্নত করা যায়?


165

আমার কাছে প্রায় 10 টি ক্ষেত্র, প্রায় 2MB ডেটা সহ কয়েক হাজার সারিটির একটি বিশাল ডেটাসেট রয়েছে। আমার এটি ব্রাউজারে প্রদর্শন করা দরকার। সর্বাধিক সোজাসুজি পদ্ধতির (ডেটা আনার, এটির মধ্যে রাখুন $scope, ng-repeat=""এটির কাজটি করা যাক ) ভাল কাজ করে, তবে এটি ডিওমে নোডগুলি সন্নিবেশ করা শুরু করলে প্রায় অর্ধেক মিনিট ব্রাউজারকে হিমশীতল করে দেয়। এই সমস্যাটির কাছে আমার কীভাবে যোগাযোগ করা উচিত?

একটি বিকল্প হ'ল সারিগুলি $scopeক্রমবর্ধমানভাবে সংযোজন ngRepeatকরা এবং পরেরটিতে যাওয়ার আগে একটি অংশকে ডিওমে inোকানো শেষ করার জন্য অপেক্ষা করা। কিন্তু এএফএআইজি এনজিপিপিটি "পুনরাবৃত্তি" শেষ করার পরে ফিরে রিপোর্ট করে না, তাই এটি কুশ্রী হতে চলেছে।

অন্য বিকল্পটি হ'ল সার্ভারের ডেটাগুলিকে পৃষ্ঠাগুলিতে বিভক্ত করা এবং একাধিক অনুরোধে সেগুলি আনা, তবে এটি এমনকি খারাপ।

আমি এমন কিছু সন্ধানের জন্য কৌনিক ডকুমেন্টেশনের মাধ্যমে দেখেছি ng-repeat="data in dataset" ng-repeat-steps="500", কিন্তু কিছুই পাইনি। আমি কৌণিক উপায়ে মোটামুটি নতুন, সুতরাং এটি সম্ভব যে আমি পয়েন্টটি পুরোপুরি মিস করছি। এটির সেরা অনুশীলনগুলি কী কী?


10
আপনি কি সত্যিই সমস্ত সারি প্রদর্শন করতে চান? ব্যবহারকারী কেবল দেখতে পাবে এমন অনেকগুলি সারি প্রদর্শন করার বিষয়ে। যেমন আপনি limitToকেবল 20 আইটেম প্রদর্শন করতে ব্যবহার করতে পারেন : <p ng-repeat="data in dataset | limitTo:20">{{data}}</p>এটি কেবল 20 টি আইটেম দেখায়। তারপরে আপনি পৃষ্ঠাগুলি ব্যবহার করতে পারবেন এবং পরবর্তী 10 টি আইটেম বা এর মতো কিছু প্রদর্শন করতে পারেন। :)
AndreM96

"পুনরাবৃত্তি" সমাপ্তির পরে "প্রতিবেদন করুন" জিনিসটির জন্য আপনি এনজি-রিপিট ছাড়াও একটি কাস্টম নির্দেশিকা ব্যবহার করতে পারেন। (এখানে নির্বাচিত উত্তর দেখুন) stackoverflow.com/questions/13471129/...
mayankcpdixit

এই প্রশ্নটি উল্লেখ করুন এটি অবশ্যই আপনাকে সহায়তা করবে। [লিঙ্কের বিবরণটি এখানে প্রবেশ করুন] [1] [1]: স্ট্যাকওভারফ্লো
মহেশ

উত্তর:


159

আমি @ AndreM96 এর সাথে একমত যে সর্বোত্তম পন্থা হ'ল সীমাবদ্ধতার একটি সীমিত পরিমাণ, দ্রুত এবং উন্নত ইউএক্স প্রদর্শন করা, এটি একটি পৃষ্ঠাগুলি দ্বারা বা একটি অসীম স্ক্রোল দিয়ে করা যেতে পারে।

Angular সহ অসীম স্ক্রোল সীমাবদ্ধতা ফিল্টার সহ সত্যিই সহজ । আপনাকে কেবল প্রাথমিক সীমাটি নির্ধারণ করতে হবে এবং যখন ব্যবহারকারী আরও ডেটা চাইবে (আমি সরলতার জন্য একটি বোতাম ব্যবহার করছি) আপনি সীমাটি বৃদ্ধি করবেন।

<table>
    <tr ng-repeat="d in data | limitTo:totalDisplayed"><td>{{d}}</td></tr>
</table>
<button class="btn" ng-click="loadMore()">Load more</button>

//the controller
$scope.totalDisplayed = 20;

$scope.loadMore = function () {
  $scope.totalDisplayed += 20;  
};

$scope.data = data;

এখানে একটি জেএসবিন রয়েছে

ফোনের ক্ষেত্রে এই পদ্ধতির সমস্যা হতে পারে কারণ প্রচুর ডেটা স্ক্রোল করার সময় সাধারণত এগুলি পিছিয়ে থাকে, তাই এই ক্ষেত্রে আমি মনে করি একটি পৃষ্ঠা বাছাই আরও ভাল ফিট করে।

এটি করার জন্য আপনাকে প্রদর্শিত হতে যাওয়া ডেটার শুরুর পয়েন্টটি নির্ধারণ করতে সীমাবদ্ধতা ফিল্টার এবং একটি কাস্টম ফিল্টার প্রয়োজন।

এখানে একটি জেএসবিন রয়েছে যা একটি পৃষ্ঠা রয়েছে।


ভাল বিকল্প !!! আপনি যদি কোনও আইটেম দেখানোর জন্য আবদ্ধ হন তবে আপনি যে কোনও পদ্ধতি ব্যবহার করবেন তা জানেন। কোনও লোডিং সাইন বা একের পর এক ডিওএম বা somethingোকানো হয়েছে?
mayankcpdixit

আপনি কী বোঝাতে চান ডেটা আনার সময় একটি "লোডিং ..." বা অন্য কিছু প্রদর্শন করুন?
বারট্র্যান্ড

1
@ সুমিট লিমিটটি এনজি-রিপিট স্কোপে প্রয়োগ করা হবে, ফলস্বরূপ একটি নতুন অ্যারে হবে যা এনজি-রিপিটকে পাস করা হবে, আপনার ডেটা অ্যারে এখনও একই রকম এবং আপনি এখনও সমস্ত সামগ্রী অনুসন্ধান করতে পারেন।
বারট্র্যান্ড

12
যদি ব্যবহারকারী 10 বার লোডমোর টিপে এবং প্রতিটি প্রেস আরও 100 টি আইটেম যুক্ত করে, তবে এটি কীভাবে কর্মক্ষমতা উন্নত করতে পারে?
hariszaman

5
@hariszaman আমি সম্মত এটি কার্যকারিতা উন্নতি করে না। এটি কেবল খারাপ পারফরম্যান্সে বিলম্ব করে। আপনি যদি ভার্চুয়ালাইজিং না করেন (তবে ইউআই-গ্রিড যা করে) অনন্ত স্ক্রোল আপনাকে সমস্যায় ফেলবে।
রিচার্ড

41

সবচেয়ে উষ্ণতম - এবং তর্কযোগ্যভাবে সবচেয়ে পরিমাপযোগ্য - বড় ডেটাসেটের সাহায্যে এই চ্যালেঞ্জগুলি পরাস্ত করার পদ্ধতিকে অয়নিকের সংগ্রহের পুনর্নির্দেশের নির্দেশিকা এবং এর মতো অন্যান্য বাস্তবায়নের মাধ্যমে মূর্ত করা হয়েছে । এটির জন্য অভিনব শব্দটি 'অবসেশন কুলিং' , তবে আপনি এটি যোগ করতে পারেন: কেবলমাত্র রেন্ডারডম ডিওএম উপাদানগুলির গণনাটিকে একটি স্বেচ্ছাসেবী (তবে এখনও উচ্চতর) 50, 100, 500 এর মতো পৃষ্ঠাযুক্ত সংখ্যায় সীমাবদ্ধ করবেন না ... পরিবর্তে , ব্যবহারকারী যতটা দেখতে পাবে কেবল তার মধ্যে সীমাবদ্ধ করুন

আপনি যদি "অসীম স্ক্রোলিং" নামে পরিচিত এমন কিছু করেন তবে আপনি প্রাথমিক DOM গণনা কিছুটা কমিয়ে দিচ্ছেন তবে কিছুটা সতেজ হওয়ার পরে তা দ্রুত ফুলে যায় কারণ এই সমস্ত নতুন উপাদানগুলি কেবল নীচে সজ্জিত। স্ক্রোলিং একটি ক্রল এ আসে, কারণ স্ক্রোলিং সমস্ত উপাদান গণনা সম্পর্কে। এটি সম্পর্কে অসীম কিছুই নেই।

যেহেতু, collectionRepeatপদ্ধতির যেমন ভিউপোর্টে মাপসই করা হবে, এবং তারপর অনেক উপাদান হিসাবে শুধুমাত্র ব্যবহার করা তাদের জিনিসকে । যেহেতু একটি উপাদান দৃষ্টির বাইরে চলে যায়, এটি রেন্ডার ট্রি থেকে আলাদা হয়, তালিকার কোনও নতুন আইটেমের জন্য ডেটা দিয়ে রিফিল করে, তারপরে তালিকার অন্য প্রান্তে রেন্ডার ট্রিটিতে পুনরায় সংযুক্ত হয়। এটি তৈরির / সনাতন চক্রের ... destroyতিহ্যবাহী চক্রের পরিবর্তে বিদ্যমান উপাদানগুলির একটি সীমাবদ্ধ সেট ব্যবহার করে, ডিওএমের ভিতরে এবং বাইরে নতুন তথ্য পাওয়ার জন্য সবচেয়ে দ্রুততম উপায় known এই পদ্ধতির ব্যবহার করে আপনি সত্যই একটি অসীম স্ক্রোল প্রয়োগ করতে পারেন ।

নোট করুন যে আপনাকে আয়নিক / হ্যাক / অ্যাডাপ্ট করতে collectionRepeatবা এটির মতো অন্য কোনও সরঞ্জাম ব্যবহার করতে হবে না। এ কারণেই তারা এটিকে ওপেন সোর্স বলে। :-) (এটি বলেছিল, আয়নিক টিম আপনার মনোযোগের যোগ্য, কিছু চমকপ্রদ কাজ করছে)


প্রতিক্রিয়াতে খুব অনুরূপ কিছু করার কমপক্ষে একটি চমৎকার উদাহরণ রয়েছে। কেবলমাত্র আপডেট হওয়া সামগ্রীর সাহায্যে উপাদানগুলি পুনর্ব্যবহার করার পরিবর্তে, আপনি কেবল তেমন গাছটিতে এমন কিছু রেন্ডার না করতে বেছে নিচ্ছেন যা দৃশ্যমান নয়। এটি 5000 আইটেমগুলিতে দ্রুত জ্বলছে, যদিও তাদের খুব সাধারণ POC বাস্তবায়ন কিছুটা ঝাঁকুনির অনুমতি দেয় ...


এছাড়াও ... অন্যান্য পোস্টগুলির কিছু প্রতিধ্বনিত track byকরা ছোট ছোট ডেটাসেট সহ এমনকি ব্যবহার করা গুরুতরভাবে সহায়ক। এটি বাধ্যতামূলক বিবেচনা করুন।


আয়নিক টিমের দুর্দান্ত ধারণা। আমি ভাবছি যদি এটি থেকে আসে তবে কীভাবে দেশী দৃষ্টিভঙ্গি উপস্থাপন করা হয়?
ব্র্যাডলি বন্যা

উদাহরণস্বরূপ, আইওএসের ইউআইটিএবলভিউ বড় ডেটা সেট রেন্ডার করতে একই পন্থা ব্যবহার করে। আমি মনে করি এটি অনেকগুলি নেটিভ ভিউতে ব্যবহৃত একটি সাধারণ পদ্ধতি।
দিমিত্রি কোটেনকো

36

আমি এটি দেখতে সুপারিশ:

অ্যাঙ্গুলারজেএস অনুকূলিতকরণ: 1200 মিমি থেকে 35 এমএস

4 টি অংশে এনজি-রিপিটকে অনুকূল করে তারা একটি নতুন নির্দেশনা তৈরি করেছে:

অপ্টিমাইজেশন # 1: ক্যাশে ডোম উপাদান

অপ্টিমাইজেশন # 2: সমষ্টিগত প্রহরীগণ

অপ্টিমাইজেশন # 3: উপাদান তৈরি স্থগিত করুন

অপ্টিমাইজেশন # 4: লুকানো উপাদানগুলির জন্য বাইপাস পর্যবেক্ষক

প্রকল্পটি এখানে গিথুবে রয়েছে:

ব্যবহার:

1- এই ফাইলগুলিকে আপনার একক পৃষ্ঠার অ্যাপে অন্তর্ভুক্ত করুন:

  • core.js
  • scalyr.js
  • slyEvaluate.js
  • slyRepeat.js

2- মডিউল নির্ভরতা যুক্ত করুন:

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

3- এনজি-রিপিট প্রতিস্থাপন করুন

<tr sly-repeat="m in rows"> .....<tr>

উপভোগ করুন!


4
আমি মনে করি এই scalyr.js এর মধ্যে অন্যদের ফাইলগুলি ইতিমধ্যে অন্তর্ভুক্ত রয়েছে। কারণ বিল্ড স্ক্রিপ্টের ফলাফল।
dnocode

আমি Scalyr ব্যবহার করার চেষ্টা করেছি কিন্তু ফিল্টার কাজ করে না। <tr sly-repeat = "main.customers | অপশন | ফিল্টার: অনুসন্ধান_পিন্ড | সীমাবদ্ধতা: 20">
aldesabido

এটি অত্যন্ত সহায়ক। আমি এটি একটি AngularJS 1.6 অ্যাপে ব্যবহার করছি যেখানে ক্লায়েন্ট প্রচুর পরিমাণে ডেটা দেখতে চায় (সাধারণত আমি পেজিং / হ্রাসিত ডেটা উপাদানগুলির সাথে ফর্মগুলি ডিজাইন করি তবে ক্লায়েন্টকে একবারে প্রচুর ডেটা তুলনা করতে হবে)। এই লাইব্রেরির কারণে এখনও অবধি ঘরগুলির গ্রিড অপ্রয়োজনীয় থেকে পুরোপুরি সূক্ষ্ম হয়ে গেছে। তবে এই লিবটি AngularJS 1.2 দিনের মধ্যে ফিরে লেখা হয়েছিল তাই আমি সমস্যার সন্ধানের জন্য যত্ন সহকারে পরীক্ষা করব।
ফ্লায়ার

আমি এই সময়ে যা বলতে পারি তা থেকে গেটেডস্কোপ.জেএস ফাইল (323 লাইন) কেবলমাত্র অ্যাংুলারজেএস-এর আরও বর্তমান সংস্করণগুলিতে চালনীয় হওয়ার জন্য যাচাই করা দরকার। এই টান অনুরোধটি উল্লেখযোগ্য: github.com/karser/angular/commit/… । এটি স্বাক্ষর রুটস্কোপ আপডেট করে $ নতুন।
ফ্লায়ার

চারটি জেএস ফাইল অন্তর্ভুক্ত করা হয়েছে এবং ব্যবহৃত হয়েছে sly-repeatতবে কিছুই আমাকে ফল দেয়নি ফলাফল এখনও ধীর এবং ব্রাউজারের লঙ্ঘনও হতে পারে [Violation] 'setTimeout' handler took 54ms,[Violation] 'scroll' handler took 1298ms
গৌরব আগরওয়াল

15

উপরের সমস্ত ইঙ্গিতগুলি যেমন ট্র্যাক বাই এবং আরও ছোট লুপগুলির পাশাপাশি, এটি আমাকেও অনেক সহায়তা করেছিল

<span ng-bind="::stock.name"></span>

এই কোডটির এই অংশটি নামটি একবার লোড হয়ে গেলে তা মুদ্রণ করতে পারে এবং এর পরে এটি দেখা বন্ধ করে দেয়। একইভাবে, এনজি-পুনরাবৃত্তিগুলির জন্য, এটি হিসাবে ব্যবহার করা যেতে পারে

<div ng-repeat="stock in ::ctrl.stocks">{{::stock.name}}</div>

তবে এটি কেবল অ্যাঙ্গুলারজেএস সংস্করণ 1.3 এবং উচ্চতর জন্য কাজ করে। Http://www.befundoo.com/blog/optimizing-ng-repeat-in-angularjs/ থেকে


আপনি ::পুনরাবৃত্তি পাশাপাশি অভিব্যক্তি প্রয়োজন? দস্তাবেজ অন্যথায় বলে, তবে এটি যে কাজ করছে তা পরীক্ষা করার উপায় সম্পর্কে আমি নিশ্চিত নই। docs.angularjs.org/guide/expression
ক্রিশ্চিয়ান রামিরেজ

12

পারফরম্যান্স বাড়ানোর জন্য আপনি "ট্র্যাক বাই" ব্যবহার করতে পারেন:

<div ng-repeat="a in arr track by a.trackingKey">

তুলনায় দ্রুততর:

<div ng-repeat="a in arr">

রেফ: https://www.airpair.com/angularjs/posts/angularjs-performance-large-applications


1
এটি কার্য সম্পাদনের জন্য সত্যই সহায়তা করে না। Jsperf.com/ng-repeat-vs-ng-repeat-with-trace-by-id
ইল্টার

ট্র্যাক দ্বারা আপনি যখনই নতুন ডেটা পাবেন প্রতিবার থেকেই অ্যারে উপাদানটি ট্র্যাক করবেন না। ফলস্বরূপ এই কর্মক্ষমতা উন্নত।
ব্যবহারকারী 1920302

2
এনজি-রিপিটের ডেটা পরিবর্তিত হলেই এটি কার্যকর হয় is প্রাথমিক লোডের জন্য, এটি কোনও পারফরম্যান্স উন্নতি তৈরি করতে পারে না।
সুমেশ কুতান

11

আপনার সমস্ত সারিগুলির সমান উচ্চতা থাকলে আপনার অবশ্যই ভার্চুয়ালাইজিং এনজি-রিপিটটি একবার দেখে নেওয়া উচিত: http://kamilkp.github.io/angular-vs-repeat/

এই ডেমোটি খুব আশাব্যঞ্জক দেখাচ্ছে (এবং এটি আন্তঃ স্ক্রোলিং সমর্থন করে)


2
মোবাইলে স্ক্রোল পারফরম্যান্স গ্রহণযোগ্য নয় (স্ক্রোল ইভেন্টগুলি মোবাইল আইওএসে জ্বলে উঠবে না (কেবল 8 থেকে আপ)
জনি

9

বিধি নং 1: ব্যবহারকারীকে কখনই কোনও কিছুর জন্য অপেক্ষা করতে দেওয়া উচিত নয়।

যে 10 সেকেন্ডের প্রয়োজন এমন একটি জীবন বর্ধমান পৃষ্ঠা মনে রাখায় ফাঁকা স্ক্রিনের আগে 3 সেকেন্ড অপেক্ষা করার চেয়ে দ্রুত দ্রুত উপস্থিত হয় এবং সমস্ত একবারে পাওয়া যায়।

সুতরাং পৃষ্ঠাটি দ্রুত করার পরিবর্তে, চূড়ান্ত ফলাফলটি ধীরে ধীরে হলেও পৃষ্ঠাটি দ্রুত প্রদর্শিত হবে appear

function applyItemlist(items){
    var item = items.shift();
    if(item){
        $timeout(function(){
            $scope.items.push(item);
            applyItemlist(items);
        }, 0); // <-- try a little gap of 10ms
    }
}

উপরের কোডটি সারি-সারি সারি বাড়ার জন্য তালিকাটি প্রদর্শিত হবে এবং এটি সমস্ত একবারে রেন্ডারের চেয়ে ধীর। তবে ব্যবহারকারীর জন্য এটি দ্রুততর বলে মনে হচ্ছে।


এইচটিএমএল পৃষ্ঠায় এই ফাংশনটি কীভাবে ব্যবহার করবেন?
আন্তোনিস

9

ভার্চুয়াল স্ক্রোলিং বিশাল তালিকা এবং বড় ডেটাসেটের সাথে কাজ করার সময় স্ক্রোলিং কার্যকারিতা উন্নত করার আরেকটি উপায়।

এটি প্রয়োগের একটি উপায় হ'ল কৌণিক উপাদান ব্যবহার করা md-virtual-repeatযেমন এটি 50,000 আইটেম সহ এই ডেমোতে প্রদর্শিত হয়

ভার্চুয়াল পুনরাবৃত্তির ডকুমেন্টেশন থেকে সরাসরি নেওয়া হয়েছে:

ভার্চুয়াল পুনরাবৃত্তি এনজি-রিপিটের সীমিত বিকল্প যা কেবল পাত্রে ভরাট করার জন্য যথেষ্ট পরিমাণ ডোম নোড সরবরাহ করে এবং তাদের ব্যবহারকারীর স্ক্রোল হিসাবে পুনর্ব্যবহার করে।


2
বাহ, আমি মনে করি এটি সবচেয়ে আকর্ষণীয় উত্তর। এটি কি কৌণিকের পুরানো সংস্করণের সাথে কাজ করবে? (উদাহরণস্বরূপ
ভার্স

2
@ থারিকুনগ্রোহোটোমো দয়া করে নোট করুন যে কৌণিক উপাদান ব্যবহারের জন্য কৌণিক 1.3.x বা তার বেশি ব্যবহার করা প্রয়োজন। সমর্থনের জন্য ধন্যবাদ, আমি পাশাপাশি ভার্চুয়াল পুনরাবৃত্তি দ্বারা বিস্মিত এবং আমরা ইতিমধ্যে ফলাফলের একটি দীর্ঘ দীর্ঘ তালিকা প্রদর্শন করে যে একটি মোবাইল অ্যাপ্লিকেশন এ এটি ব্যবহার করে।
সারান্টিস তোফাস

6

আরেকটি সংস্করণ @ স্টেফমিও

পৃথকভাবে প্রতিটি আইটেম যুক্ত করার পরিবর্তে আমরা অংশগুলি দ্বারা আইটেম যুক্ত করতে পারি।

// chunks function from here: 
// http://stackoverflow.com/questions/8495687/split-array-into-chunks#11764168
var chunks = chunk(folders, 100);

//immediate display of our first set of items
$scope.items = chunks[0];

var delay = 100;
angular.forEach(chunks, function(value, index) {
    delay += 100;

    // skip the first chuck
    if( index > 0 ) {
        $timeout(function() {
            Array.prototype.push.apply($scope.items,value);
        }, delay);
    }       
});

আকর্ষণীয় ধারণা। আমি এটি 8000 ডলার উপাদানের অ্যারে চেষ্টা করেছি এবং এটি পৃষ্ঠাটিকে প্রাথমিকভাবে আরও প্রতিক্রিয়াশীল করার সময়, প্রতিটি অংশের পরে এটি কম প্রতিক্রিয়াশীল হয়ে ওঠে।
পল ব্রান্নান

500 টিরও বেশি আইটেম থাকার পরে এটি আমার অ্যাপটিতে একটি বিশাল সমস্যা ছিল। আমি পরিবর্তে পৃষ্ঠা বা অবিরাম লোডিংয়ের পরামর্শ দিই।
joalcego

0

কখনও কখনও যা ঘটেছিল, আপনি কিছু এমএসে সার্ভার (বা ব্যাক-এন্ড) থেকে ডেটা পান ( উদাহরণস্বরূপ আমি এটি 100 মিমি ধরে নিচ্ছি) তবে আমাদের ওয়েব পৃষ্ঠায় প্রদর্শিত হতে আরও সময় লাগে (ধরা যাক এটি 900 মিমি অবধি নিচ্ছে) প্রদর্শন)।

সুতরাং, এখানে যা ঘটছে তা 800 মিমি এটি কেবল ওয়েব পৃষ্ঠাটি রেন্ডার করার জন্য নিচ্ছে।

আমি আমার ওয়েব অ্যাপ্লিকেশনটিতে যা করেছি তা হ'ল, আমি পৃষ্ঠাগুলি ব্যবহার করেছি (অথবা আপনি অসীম স্ক্রোলিং ব্যবহার করতে পারেন ) ডেটা তালিকা প্রদর্শন করতে। ধরা যাক আমি 50 ডেটা / পৃষ্ঠা দেখাব।

সুতরাং আমি একবারে সমস্ত ডেটা রেন্ডার করব না, প্রাথমিকভাবে কেবল 50 টি ডেটা লোড করছি যা কেবল 50 মিমি লাগে (আমি এখানে ধরে নিচ্ছি)।

সুতরাং এখানে মোট সময় 900ms থেকে 150ms এ কমেছে, একবার ব্যবহারকারীদের পরবর্তী পৃষ্ঠার অনুরোধ করে তারপরে পরবর্তী 50 ডেটা প্রদর্শন করা হবে।

আশা করি এটি আপনাকে পারফরম্যান্সের উন্নতি করতে সহায়তা করবে। শুভকামনা


0
Created a directive (ng-repeat with lazy loading) 

যা পৃষ্ঠার নীচে পৌঁছায় এবং লোড করা আগের ডেটা অর্ধেক সরিয়ে দেয় এবং আবার ডিভের শীর্ষে পৌঁছে গেলে পূর্বের ডেটা (পৃষ্ঠা সংখ্যার উপর নির্ভর করে) বর্তমান ডেটার অর্ধেক অপসারণ করে লোড করা হবে সুতরাং DOM এ এক সময়ে কেবল সীমিত ডেটা উপস্থিত থাকে যা লোডের উপরে পুরো ডেটা রেন্ডারিংয়ের পরিবর্তে আরও ভাল পারফরম্যান্সের দিকে নিয়ে যেতে পারে।

এইচটিএমএল কোড:

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
    <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.20/angular.js" data-semver="1.3.20"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="ListController">
  <div class="row customScroll" id="customTable" datafilter pagenumber="pageNumber" data="rowData" searchdata="searchdata" itemsPerPage="{{itemsPerPage}}"  totaldata="totalData"   selectedrow="onRowSelected(row,row.index)"  style="height:300px;overflow-y: auto;padding-top: 5px">

    <!--<div class="col-md-12 col-xs-12 col-sm-12 assign-list" ng-repeat="row in CRGC.rowData track by $index | orderBy:sortField:sortReverse | filter:searchFish">-->
    <div class="col-md-12 col-xs-12 col-sm-12 pdl0 assign-list" style="padding:10px" ng-repeat="row in rowData" ng-hide="row[CRGC.columns[0].id]=='' && row[CRGC.columns[1].id]==''">
        <!--col1-->

        <div ng-click ="onRowSelected(row,row.index)"> <span>{{row["sno"]}}</span> <span>{{row["id"]}}</span> <span>{{row["name"]}}</span></div>
      <!--   <div class="border_opacity"></div> -->
    </div>

</div>

  </body>

</html>

কৌণিক কোড:

var app = angular.module('plunker', []);
var x;
ListController.$inject = ['$scope', '$timeout', '$q', '$templateCache'];

function ListController($scope, $timeout, $q, $templateCache) {
  $scope.itemsPerPage = 40;
  $scope.lastPage = 0;
  $scope.maxPage = 100;
  $scope.data = [];
  $scope.pageNumber = 0;


  $scope.makeid = function() {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (var i = 0; i < 5; i++)
      text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
  }


  $scope.DataFormFunction = function() {
      var arrayObj = [];
      for (var i = 0; i < $scope.itemsPerPage*$scope.maxPage; i++) {
          arrayObj.push({
              sno: i + 1,
              id: Math.random() * 100,
              name: $scope.makeid()
          });
      }
      $scope.totalData = arrayObj;
      $scope.totalData = $scope.totalData.filter(function(a,i){ a.index = i; return true; })
      $scope.rowData = $scope.totalData.slice(0, $scope.itemsperpage);
    }
  $scope.DataFormFunction();

  $scope.onRowSelected = function(row,index){
    console.log(row,index);
  }

}

angular.module('plunker').controller('ListController', ListController).directive('datafilter', function($compile) {
  return {
    restrict: 'EAC',
    scope: {
      data: '=',
      totalData: '=totaldata',
      pageNumber: '=pagenumber',
      searchdata: '=',
      defaultinput: '=',
      selectedrow: '&',
      filterflag: '=',
      totalFilterData: '='
    },
    link: function(scope, elem, attr) {
      //scope.pageNumber = 0;
      var tempData = angular.copy(scope.totalData);
      scope.totalPageLength = Math.ceil(scope.totalData.length / +attr.itemsperpage);
      console.log(scope.totalData);
      scope.data = scope.totalData.slice(0, attr.itemsperpage);
      elem.on('scroll', function(event) {
        event.preventDefault();
      //  var scrollHeight = angular.element('#customTable').scrollTop();
      var scrollHeight = document.getElementById("customTable").scrollTop
        /*if(scope.filterflag && scope.pageNumber != 0){
        scope.data = scope.totalFilterData;
        scope.pageNumber = 0;
        angular.element('#customTable').scrollTop(0);
        }*/
        if (scrollHeight < 100) {
          if (!scope.filterflag) {
            scope.scrollUp();
          }
        }
        if (angular.element(this).scrollTop() + angular.element(this).innerHeight() >= angular.element(this)[0].scrollHeight) {
          console.log("scroll bottom reached");
          if (!scope.filterflag) {
            scope.scrollDown();
          }
        }
        scope.$apply(scope.data);

      });

      /*
       * Scroll down data append function
       */
      scope.scrollDown = function() {
          if (scope.defaultinput == undefined || scope.defaultinput == "") { //filter data append condition on scroll
            scope.totalDataCompare = scope.totalData;
          } else {
            scope.totalDataCompare = scope.totalFilterData;
          }
          scope.totalPageLength = Math.ceil(scope.totalDataCompare.length / +attr.itemsperpage);
          if (scope.pageNumber < scope.totalPageLength - 1) {
            scope.pageNumber++;
            scope.lastaddedData = scope.totalDataCompare.slice(scope.pageNumber * attr.itemsperpage, (+attr.itemsperpage) + (+scope.pageNumber * attr.itemsperpage));
            scope.data = scope.totalDataCompare.slice(scope.pageNumber * attr.itemsperpage - 0.5 * (+attr.itemsperpage), scope.pageNumber * attr.itemsperpage);
            scope.data = scope.data.concat(scope.lastaddedData);
            scope.$apply(scope.data);
            if (scope.pageNumber < scope.totalPageLength) {
              var divHeight = $('.assign-list').outerHeight();
              if (!scope.moveToPositionFlag) {
                angular.element('#customTable').scrollTop(divHeight * 0.5 * (+attr.itemsperpage));
              } else {
                scope.moveToPositionFlag = false;
              }
            }


          }
        }
        /*
         * Scroll up data append function
         */
      scope.scrollUp = function() {
          if (scope.defaultinput == undefined || scope.defaultinput == "") { //filter data append condition on scroll
            scope.totalDataCompare = scope.totalData;
          } else {
            scope.totalDataCompare = scope.totalFilterData;
          }
          scope.totalPageLength = Math.ceil(scope.totalDataCompare.length / +attr.itemsperpage);
          if (scope.pageNumber > 0) {
            this.positionData = scope.data[0];
            scope.data = scope.totalDataCompare.slice(scope.pageNumber * attr.itemsperpage - 0.5 * (+attr.itemsperpage), scope.pageNumber * attr.itemsperpage);
            var position = +attr.itemsperpage * scope.pageNumber - 1.5 * (+attr.itemsperpage);
            if (position < 0) {
              position = 0;
            }
            scope.TopAddData = scope.totalDataCompare.slice(position, (+attr.itemsperpage) + position);
            scope.pageNumber--;
            var divHeight = $('.assign-list').outerHeight();
            if (position != 0) {
              scope.data = scope.TopAddData.concat(scope.data);
              scope.$apply(scope.data);
              angular.element('#customTable').scrollTop(divHeight * 1 * (+attr.itemsperpage));
            } else {
              scope.data = scope.TopAddData;
              scope.$apply(scope.data);
              angular.element('#customTable').scrollTop(divHeight * 0.5 * (+attr.itemsperpage));
            }
          }
        }
    }
  };
});

নির্দেশ সহ ডেমো

Another Solution: If you using UI-grid in the project then  same implementation is there in UI grid with infinite-scroll.

বিভাগের উচ্চতার উপর নির্ভর করে এটি ডেটা লোড করে এবং স্ক্রোলের উপর নতুন ডেটা সংযোজন করা হবে এবং পূর্ববর্তী ডেটা সরানো হবে।

এইচটিএমএল কোড:

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <link rel="stylesheet" href="https://cdn.rawgit.com/angular-ui/bower-ui-grid/master/ui-grid.min.css" type="text/css" />
    <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.20/angular.js" data-semver="1.3.20"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.0.6/ui-grid.js"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="ListController">
     <div class="input-group" style="margin-bottom: 15px">
      <div class="input-group-btn">
        <button class='btn btn-primary' ng-click="resetList()">RESET</button>
      </div>
      <input class="form-control" ng-model="search" ng-change="abc()">
    </div>

    <div data-ui-grid="gridOptions" class="grid" ui-grid-selection  data-ui-grid-infinite-scroll style="height :400px"></div>

    <button ng-click="getProductList()">Submit</button>
  </body>

</html>

কৌনিক কোড:

var app = angular.module('plunker', ['ui.grid', 'ui.grid.infiniteScroll', 'ui.grid.selection']);
var x;
angular.module('plunker').controller('ListController', ListController);
ListController.$inject = ['$scope', '$timeout', '$q', '$templateCache'];

function ListController($scope, $timeout, $q, $templateCache) {
    $scope.itemsPerPage = 200;
    $scope.lastPage = 0;
    $scope.maxPage = 5;
    $scope.data = [];

    var request = {
        "startAt": "1",
        "noOfRecords": $scope.itemsPerPage
    };
    $templateCache.put('ui-grid/selectionRowHeaderButtons',
        "<div class=\"ui-grid-selection-row-header-buttons \" ng-class=\"{'ui-grid-row-selected': row.isSelected}\" ><input style=\"margin: 0; vertical-align: middle\" type=\"checkbox\" ng-model=\"row.isSelected\" ng-click=\"row.isSelected=!row.isSelected;selectButtonClick(row, $event)\">&nbsp;</div>"
    );


    $templateCache.put('ui-grid/selectionSelectAllButtons',
        "<div class=\"ui-grid-selection-row-header-buttons \" ng-class=\"{'ui-grid-all-selected': grid.selection.selectAll}\" ng-if=\"grid.options.enableSelectAll\"><input style=\"margin: 0; vertical-align: middle\" type=\"checkbox\" ng-model=\"grid.selection.selectAll\" ng-click=\"grid.selection.selectAll=!grid.selection.selectAll;headerButtonClick($event)\"></div>"
    );

    $scope.gridOptions = {
        infiniteScrollDown: true,
        enableSorting: false,
        enableRowSelection: true,
        enableSelectAll: true,
        //enableFullRowSelection: true,
        columnDefs: [{
            field: 'sno',
            name: 'sno'
        }, {
            field: 'id',
            name: 'ID'
        }, {
            field: 'name',
            name: 'My Name'
        }],
        data: 'data',
        onRegisterApi: function(gridApi) {
            gridApi.infiniteScroll.on.needLoadMoreData($scope, $scope.loadMoreData);
            $scope.gridApi = gridApi;
        }
    };
    $scope.gridOptions.multiSelect = true;
    $scope.makeid = function() {
        var text = "";
        var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

        for (var i = 0; i < 5; i++)
            text += possible.charAt(Math.floor(Math.random() * possible.length));

        return text;
    }
    $scope.abc = function() {
        var a = $scope.search;
        x = $scope.searchData;
        $scope.data = x.filter(function(arr, y) {
            return arr.name.indexOf(a) > -1
        })
        console.log($scope.data);
        if ($scope.gridApi.grid.selection.selectAll)
            $timeout(function() {
                $scope.gridApi.selection.selectAllRows();
            }, 100);
    }


    $scope.loadMoreData = function() {
        var promise = $q.defer();
        if ($scope.lastPage < $scope.maxPage) {
            $timeout(function() {
                var arrayObj = [];
                for (var i = 0; i < $scope.itemsPerPage; i++) {
                    arrayObj.push({
                        sno: i + 1,
                        id: Math.random() * 100,
                        name: $scope.makeid()
                    });
                }

                if (!$scope.search) {
                    $scope.lastPage++;
                    $scope.data = $scope.data.concat(arrayObj);
                    $scope.gridApi.infiniteScroll.dataLoaded();
                    console.log($scope.data);
                    $scope.searchData = $scope.data;
                    // $scope.data = $scope.searchData;
                    promise.resolve();
                    if ($scope.gridApi.grid.selection.selectAll)
                        $timeout(function() {
                            $scope.gridApi.selection.selectAllRows();
                        }, 100);
                }


            }, Math.random() * 1000);
        } else {
            $scope.gridApi.infiniteScroll.dataLoaded();
            promise.resolve();
        }
        return promise.promise;
    };

    $scope.loadMoreData();

    $scope.getProductList = function() {

        if ($scope.gridApi.selection.getSelectedRows().length > 0) {
            $scope.gridOptions.data = $scope.resultSimulatedData;
            $scope.mySelectedRows = $scope.gridApi.selection.getSelectedRows(); //<--Property undefined error here
            console.log($scope.mySelectedRows);
            //alert('Selected Row: ' + $scope.mySelectedRows[0].id + ', ' + $scope.mySelectedRows[0].name + '.');
        } else {
            alert('Select a row first');
        }
    }
    $scope.getSelectedRows = function() {
        $scope.mySelectedRows = $scope.gridApi.selection.getSelectedRows();
    }
    $scope.headerButtonClick = function() {

        $scope.selectAll = $scope.grid.selection.selectAll;

    }
}

অসীম-স্ক্রোল ডেমো সহ ইউআই গ্রিড সহ ডেমো


একটি সমাধানের একটি লিঙ্ক স্বাগত, তবে দয়া করে আপনার উত্তরটি কার্যকর না হওয়া নিশ্চিত করুন: লিঙ্কটির চারপাশে প্রসঙ্গটি যুক্ত করুন যাতে আপনার সহ ব্যবহারকারীদের কিছু ধারণা থাকতে পারে এটি কী এবং কেন এটি রয়েছে, তারপরে আপনি পৃষ্ঠার সর্বাধিক প্রাসঙ্গিক অংশটি উদ্ধৃত করুন লক্ষ্য পৃষ্ঠাটি অনুপলব্ধ ক্ষেত্রে লিঙ্কটি পুনরায় সংযুক্ত করুন। লিঙ্কের চেয়ে সামান্য বেশি উত্তরগুলি মুছতে পারে
সা

-2

বড় ডেটা সেট এবং একাধিক মান ড্রপ ডাউন এর ng-optionsচেয়ে ব্যবহার করা ভাল ng-repeat

ng-repeatধীর গতির কারণ এটি সমস্ত আগত মানগুলিকে ছাড়িয়ে যায় তবে ng-optionsকেবলমাত্র নির্বাচন বিকল্পটিতে প্রদর্শিত হয়।

ng-options='state.StateCode as state.StateName for state in States'>

তুলনায় অনেক দ্রুত

<option ng-repeat="state in States" value="{{state.StateCode}}">
    {{state.StateName }}
</option>

আপনি এনজি-অপশনগুলির কার্যকারিতা পরীক্ষা করেছেন? আমি আমার কোডটি অনুকূলকরণের চেষ্টা করছি এবং এটি কার্যকর হয়নি। গতি এনজি-রিপিট সমান। -1
আইসেট

কেবল নির্বাচনের জন্য কাজ করে, এনজি-রিপিট উপায়টি আরও শক্তিশালী। তবুও এটি সত্য যে এনজি-পুনরাবৃত্তির চেয়ে এনজি-বিকল্পগুলি বেশ দ্রুত। অ্যাঙ্গুলারজেএস ডক্সে
কায়সার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.