AngularJS তাত্ক্ষণিক অনুসন্ধানে কীভাবে বিলম্ব করবেন?


147

আমার একটি পারফরম্যান্স ইস্যু রয়েছে যা আমি সম্বোধন করতে পারি না। আমার তাত্ক্ষণিক অনুসন্ধান আছে তবে এটি কিছুটা পিছিয়ে গেছে, যেহেতু এটি প্রতিটি অনুসন্ধান শুরু করে keyup()

জাতীয়:

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

App.controller('DisplayController', function($scope, $http) {
$http.get('data.json').then(function(result){
    $scope.entries = result.data;
});
});

এইচটিএমএল:

<input id="searchText" type="search" placeholder="live search..." ng-model="searchText" />
<div class="entry" ng-repeat="entry in entries | filter:searchText">
<span>{{entry.content}}</span>
</div>

JSON ডেটা এমনকি এত বড়, 300KB নয়, আমি মনে করি যে প্রতিটি কী-স্ট্রোকটিতে ক্রিয়া না করে, টাইপিং শেষ করার জন্য অপেক্ষা করতে অপেক্ষা করতে আমার অনুসন্ধানের জন্য ~ 1 সেকেন্ডের বিলম্ব করা উচিত think AngularJS অভ্যন্তরীণভাবে এটি করে এবং এখানে ডক্স এবং অন্যান্য বিষয়গুলি পড়ার পরে আমি একটি নির্দিষ্ট উত্তর খুঁজে পাইনি।

আমি কীভাবে তাত্ক্ষণিক অনুসন্ধানে বিলম্ব করতে পারি সে সম্পর্কে কোনও পয়েন্টারকে প্রশংসা করব।


1
আপনি থিম অ্যাপে সমস্ত জেসন পেয়ে যাচ্ছেন ... এবং তারপরে আপনার অনুসন্ধান ফিল্টারটি টাইপ করার সময় দ্বিতীয়বারের মতো ডেটা পাচ্ছে না ... এটি ইতিমধ্যে বিদ্যমান মডেলটিকে ফিল্টার করছে। আমি কি সঠিক?
ম্যাকসেম

নীচের উত্তর কি কার্যকর হয়েছে? যদি তা হয় তবে দয়া করে উত্তরটি গ্রহণ করুন। যদি তা না হয় তবে আমাকে জানান এবং আমি আরও স্পষ্ট করে বলব।
জেসন অ্যাডেন

আরে জেসন, প্রতিক্রিয়াটির জন্য ধন্যবাদ। আমি আপনার কোডটি নিয়ে খেলার চেষ্টা করছিলাম তবে ভাগ্য নেই, অনুসন্ধান আমার জন্য পুরোপুরি কাজ বন্ধ করে দেয়।
ব্রেইনকম্ব

কিছু নয়, এটি আমার খারাপ ছিল আমি কিছু উপেক্ষা করেছি। আপনার সমাধান সত্যিই কাজ করে। আপনাকে ধন্যবাদ :)
ব্রেইনক্যাম্ব

এই উত্তরটি এখানে একবার দেখুন, যা আপনাকে এমন একটি নির্দেশনা সরবরাহ করে যা আপনাকে এনজি- চেঞ্জে
ডগ

উত্তর:


121

(কৌনিক 1.3 সমাধানের জন্য নীচের উত্তর দেখুন See)

এখানে সমস্যাটি হ'ল অনুসন্ধানটি প্রতিবার মডেল পরিবর্তন হওয়ার পরে কার্যকর করা হবে যা ইনপুটটিতে প্রতিটি কীআপ ক্রিয়া।

এটি করার পরিষ্কার উপায় আছে তবে সম্ভবত সবচেয়ে সহজ উপায় হ'ল বাঁধাই স্যুইচ করা যাতে আপনার কন্ট্রোলারের অভ্যন্তরে একটি filter স্কোপ সম্পত্তি থাকে যার উপর আপনার ফিল্টার পরিচালনা করে। এইভাবে আপনি কত ঘন ঘন $ স্কোপ ভেরিয়েবল আপডেট হয় তা নিয়ন্ত্রণ করতে পারেন। এটার মতো কিছু:

জাতীয়:

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

App.controller('DisplayController', function($scope, $http, $timeout) {
    $http.get('data.json').then(function(result){
        $scope.entries = result.data;
    });

    // This is what you will bind the filter to
    $scope.filterText = '';

    // Instantiate these variables outside the watch
    var tempFilterText = '',
        filterTextTimeout;
    $scope.$watch('searchText', function (val) {
        if (filterTextTimeout) $timeout.cancel(filterTextTimeout);

        tempFilterText = val;
        filterTextTimeout = $timeout(function() {
            $scope.filterText = tempFilterText;
        }, 250); // delay 250 ms
    })
});

এইচটিএমএল:

<input id="searchText" type="search" placeholder="live search..." ng-model="searchText" />
<div class="entry" ng-repeat="entry in entries | filter:filterText">
    <span>{{entry.content}}</span>
</div>

নোট করুন যে "সুযোগ। ng-model
An

1
আমি মনে করি এটি টেমপ্লেটারটেক্সট ভেরিয়েবল ছাড়াও কাজ করবে: $ স্কোপ $ ফিল্টারটেক্সট = ভাল;}, 250); // বিলম্ব 250 এমএস})
জোস থিউউইন

@ জোসউইউউইন তখন এটি কেবলমাত্র একটি বৈশ্বিক পরিবর্তনশীল যা খারাপ অনুশীলন হিসাবে বিবেচিত এবং কঠোর মোডে অনুমোদিত নয় ।
এমবি 21

301

হালনাগাদ

এখন এটি আগের তুলনায় আরও সহজ (কৌণিক 1.3), কেবলমাত্র মডেলটিতে একটি অভিবর্তন বিকল্প যুক্ত করুন।

<input type="text" ng-model="searchStr" ng-model-options="{debounce: 1000}">

প্লাঙ্কার আপডেট হয়েছে:
http://plnkr.co/edit/4V13gK

#ModelOptions এ ডকুমেন্টেশন:
https://docs.angularjs.org/api/ng/directive/ngModelOptions

পুরানো পদ্ধতি:

এখানে কৌণিক ছাড়াও কোনও নির্ভরতা ছাড়াই অন্য পদ্ধতি।

আপনার একটি সময়সীমা নির্ধারণ করতে হবে এবং আপনার বর্তমান স্ট্রিংটিকে অতীত সংস্করণের সাথে তুলনা করতে হবে, যদি উভয়ই একই হয় তবে এটি অনুসন্ধান সম্পাদন করে।

$scope.$watch('searchStr', function (tmpStr)
{
  if (!tmpStr || tmpStr.length == 0)
    return 0;
   $timeout(function() {

    // if searchStr is still the same..
    // go ahead and retrieve the data
    if (tmpStr === $scope.searchStr)
    {
      $http.get('//echo.jsontest.com/res/'+ tmpStr).success(function(data) {
        // update the textarea
        $scope.responseData = data.res; 
      });
    }
  }, 1000);
});

এবং এটি আপনার দৃষ্টিতে যায়:

<input type="text" data-ng-model="searchStr">

<textarea> {{responseData}} </textarea>

বাধ্যতামূলক প্লাঙ্কার: http://plnkr.co/dAPmwf


2
আমার জন্য এটি গ্রহণযোগ্য চেয়ে অনেক বেশি বোধগম্য উত্তর :) ধন্যবাদ!
ওজেড_

3
এমন কোনও সমস্যা নেই যেখানে একাধিক মডেল পরিবর্তনগুলি স্ট্যাক আপ করতে পারে, যাতে নকল অনুরোধের কারণ হয়? @ জেসনএডেনের উত্তরে তিনি আগের সারিবদ্ধ ইভেন্টগুলি বাতিল করে এর যত্ন নেন।
ব্লেস্কোভিচ 17

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

এটি এখন পর্যন্ত কৌণিক 1.3
মারকাস ডব্লিউ

সতর্কতা এখানে: যদি আপনার কাছে কীপ্রেস ইভেন্ট থাকে যা জমা দেয় বা ট্রিগার করে তবে মান সীমাবদ্ধতার বিষয়টি ঘোষণা না করায় এটি সর্বশেষতম মডেল মান ছাড়াই এটি করবে। উদাহরণস্বরূপ 'foo' টাইপ করুন এবং তাত্ক্ষণিক কীপ্রেস রিটার্নে মানটি খালি স্ট্রিং হবে।
jbodily

34

কৌণিক 1.3 এ আমি এটি করব:

এইচটিএমএল:

<input ng-model="msg" ng-model-options="{debounce: 1000}">

নিয়ন্ত্রক:

$scope.$watch('variableName', function(nVal, oVal) {
    if (nVal !== oVal) {
        myDebouncedFunction();
    }
});

স্কোপ ভেরিয়েবল পরিবর্তন myDebouncedFunction()হলে মূলত আপনি কৌনিকটি চালানোর জন্য বলছেন msg। বৈশিষ্ট্যটি ng-model-options="{debounce: 1000}"নিশ্চিত করে যে msgসেকেন্ডে কেবল একবার আপডেট হতে পারে।


10
 <input type="text"
    ng-model ="criteria.searchtext""  
    ng-model-options="{debounce: {'default': 1000, 'blur': 0}}"
    class="form-control" 
    placeholder="Search" >

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


9

যারা এইচটিএমএল মার্কআপে কীআপ / কীডাউন ব্যবহার করেন তাদের জন্য। এটি ঘড়ি ব্যবহার করে না।

জাতীয়

app.controller('SearchCtrl', function ($scope, $http, $timeout) {
  var promise = '';
  $scope.search = function() {
    if(promise){
      $timeout.cancel(promise);
    }
    promise = $timeout(function() {
    //ajax call goes here..
    },2000);
  };
});

এইচটিএমএল

<input type="search" autocomplete="off" ng-model="keywords" ng-keyup="search()" placeholder="Search...">

6

Angularjs এর জন্য ঘোষিত / থ্রোটলেড মডেল আপডেট: http://jsfiddle.net/lgersman/vPsGb/3/

আপনার ক্ষেত্রে jsfiddle কোডে এই জাতীয় নির্দেশিকা ব্যবহারের চেয়ে বেশি কিছু করার নেই:

<input 
    id="searchText" 
    type="search" 
    placeholder="live search..." 
    ng-model="searchText" 
    ng-ampere-debounce
/>

এটির মূলত একটি ছোট টুকরো কোড যার মধ্যে "এনজি-অ্যাম্পিয়ার-ডেবিউন" নামে একটি একক কৌনিক নির্দেশ রয়েছে যা ব্যবহার করে http://benalman.com/projects/jquery-throcolate-debounce-plugin/ যা কোনও ডোম উপাদানকে সংযুক্ত করা যেতে পারে। নির্দেশটি সংযুক্ত ইভেন্ট হ্যান্ডলারগুলিকে পুনর্বিন্যাস করে যাতে ইভেন্টগুলি থ্রটল করার সময় এটি নিয়ন্ত্রণ করতে পারে।

আপনি এটি * মডেল কৌনিক আপডেটগুলি * কৌনিক ইভেন্ট হ্যান্ডলার এনজি- [ইভেন্ট] * জেকোরি ইভেন্ট হ্যান্ডলারদের থ্রোটলিং / ডিবাউসিংয়ের জন্য ব্যবহার করতে পারেন

একবার দেখুন: http://jsfiddle.net/lgersman/vPsGb/3/

এই নির্দেশটি অরেঞ্জভোল্ট অ্যাম্পিয়ার কাঠামোর অংশ হবে ( https://github.com/lgersman/jquery.orangevolt-ampere )।


6

এখানে কেবল পুনঃনির্দেশিত ব্যবহারকারীদের জন্য:

আপনি যেমন এনজি-মডেল-বিকল্পগুলির বৈশিষ্ট্যটি Angular 1.3ব্যবহার করতে পারেন :

<input 
       id="searchText" 
       type="search" 
       placeholder="live search..." 
       ng-model="searchText"
       ng-model-options="{ debounce: 250 }"
/>

5

আমি বিশ্বাস করি যে এই সমস্যা সমাধানের সর্বোত্তম উপায় হ'ল বেন আলমানের প্লাগইন jQuery থ্রোটল / ডেবিউন ব্যবহার করা । আমার মতে আপনার ফর্মের প্রতিটি একক ক্ষেত্রের ইভেন্টগুলি বিলম্ব করার দরকার নেই।

কেবল আপনার $ সুযোগ। $ হ্যান্ডলিং ফাংশনটি দেখুন $। এইভাবে ঘোষণা করুন:

$scope.$watch("searchText", $.debounce(1000, function() {
    console.log($scope.searchText);
}), true);

আপনাকে এটিকে একটি "স্কোপ" এ
আবদ্ধ

3

আরেকটি সমাধান হ'ল মডেল আপডেটে একটি বিলম্ব কার্যকারিতা যুক্ত করা। সাধারণ নির্দেশনাটি একটি কৌশল বলে মনে হচ্ছে:

app.directive('delayedModel', function() {
    return {
        scope: {
            model: '=delayedModel'
        },
        link: function(scope, element, attrs) {

            element.val(scope.model);

            scope.$watch('model', function(newVal, oldVal) {
                if (newVal !== oldVal) {
                    element.val(scope.model);        
                }
            });

            var timeout;
            element.on('keyup paste search', function() {
                clearTimeout(timeout);
                timeout = setTimeout(function() {
                    scope.model = element[0].value;
                    element.val(scope.model);
                    scope.$apply();
                }, attrs.delay || 500);
            });
        }
    };
});

ব্যবহার:

<input delayed-model="searchText" data-delay="500" id="searchText" type="search" placeholder="live search..." />

সুতরাং আপনি কেবল delayed-modelস্থানে ব্যবহার করুন এবং ng-modelপছন্দসই সংজ্ঞা দিন data-delay

ডেমো: http://plnkr.co/edit/OmB4C3jtUD2Wjq5kzTSU?p= পূর্বরূপ


Hey! আপনি কি ব্যাখ্যা করতে পারেন কিভাবে model: '=delayedModel'কাজ করছে? অথবা আপনি আমাকে এমন কোনও লিঙ্কে নির্দেশ করতে পারেন যেখানে আমি এটি পেতে পারি?
আকাশ অগ্রবাল

@ আকাশআগ্রাওয়াল এটি দ্বিমুখী ডেটা বাঁধাই। এটি সম্পর্কে এখানে পড়ুন docs.angularjs.org/api/ng.$compile
dfsq

1
@ ডিএফএসকিউ আমি এনজি-চেঞ্জ ব্যবহার করছিলাম এবং যখনই পাঠ্যের কোনও পরিবর্তন আসবে তখন এটি ট্রিগার করত। যখন কোনও নির্দেশিকা সংজ্ঞায়িত করা হয় তখন আমি এটি ব্যবহার করতে পারি না। element.on('change')শুধুমাত্র অস্পষ্টতার উপর ট্রিগার করে। (1) আশেপাশে কোন কাজ আছে? (২) পাঠ্য পরিবর্তনের ক্ষেত্রে নিয়ন্ত্রণকারীর কোনও ফাংশন কীভাবে কল করা যায়?
ব্যাস রাও

0

আমি এই সমস্যাটি একটি নির্দেশের সাথে সমাধান করেছি যে এটি মূলত যা করে তা হ'ল নির্দেশনাতে আমি যে বিশেষ বৈশিষ্ট্যটি দেখি তার সাথে প্রকৃত এনজি-মডেলকে আবদ্ধ করা, তারপরে একটি ডেবিউন পরিষেবা ব্যবহার করে আমি আমার নির্দেশিক বৈশিষ্ট্য আপডেট করি, সুতরাং ব্যবহারকারীটি চলকটির উপরে নজর রাখবে যে তিনি এনজি-মডেলের পরিবর্তে ডাবনো-মডেল বাঁধেন।

.directive('debounceDelay', function ($compile, $debounce) {
return {
  replace: false,
  scope: {
    debounceModel: '='
  },
  link: function (scope, element, attr) {
    var delay= attr.debounceDelay;
    var applyFunc = function () {
      scope.debounceModel = scope.model;
    }
    scope.model = scope.debounceModel;
    scope.$watch('model', function(){
      $debounce(applyFunc, delay);
    });
    attr.$set('ngModel', 'model');
    element.removeAttr('debounce-delay'); // so the next $compile won't run it again!

   $compile(element)(scope);
  }
};
});

ব্যবহার:

<input type="text" debounce-delay="1000" debounce-model="search"></input>

এবং নিয়ামক মধ্যে:

    $scope.search = "";
    $scope.$watch('search', function (newVal, oldVal) {
      if(newVal === oldVal){
        return;
      }else{ //do something meaningful }

জেফফিডে ডেমো: http://jsfiddle.net/6K7Kd/37/

$ ডিবাউন পরিষেবাটি এখানে পাওয়া যাবে: http://jsfiddle.net/Warspawn/6K7Kd/

অবশেষে বাইন্ডের নির্দেশিকা দ্বারা অনুপ্রাণিত http://jsfiddle.net/fctZH/12/


0

কৌণিক 1.3 এনজি-মডেল-অপশনগুলি ডাবনো করবে, তবে ততক্ষণে আপনাকে জোসে ইবারার মতো টাইমার ব্যবহার করতে হবে। তবে, তার কোডে তিনি প্রতিটি কী প্রেসে টাইমার চালু করেন laun এছাড়াও, তিনি সেটটাইমআউট ব্যবহার করছেন, যখন কৌনিকটিতে সেটটাইমআউট শেষে one টাইমআউট বা ব্যবহার use প্রয়োগ করতে হয়।


0

সবাই কেন ঘড়ি ব্যবহার করতে চায়? আপনি একটি ফাংশন ব্যবহার করতে পারেন:

var tempArticleSearchTerm;
$scope.lookupArticle = function (val) {
    tempArticleSearchTerm = val;

    $timeout(function () {
        if (val == tempArticleSearchTerm) {
            //function you want to execute after 250ms, if the value as changed

        }
    }, 250);
}; 

0

আমি মনে করি এখানকার সবচেয়ে সহজ উপায় হ'ল জসনকে প্রিললোড করা বা একবারে এটি লোড করা $dirtyএবং তারপরে ফিল্টার অনুসন্ধানটি বাকীগুলির যত্ন নেবে। এটি আপনাকে অতিরিক্ত http কলগুলি এবং প্রিলোডড ডেটা সহ এটির আরও দ্রুত সঞ্চয় করবে। স্মৃতি ক্ষতিকারক হবে, তবে এটি মূল্যবান।

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