জাভাস্ক্রিপ্টে পরিবর্তনশীল পরিবর্তনের জন্য শুনছি


462

যখন কোনও নির্দিষ্ট ভেরিয়েবলের মান পরিবর্তিত হয় তখন কী জেএস-এ কোনও ঘটনা ঘটতে পারে? JQuery গ্রহণ করা হয়।


@ বেনজামিন গ্রুয়েনবাউম সম্ভবত আপনি মিউটেবলঅবার্সার বলতে চান (ডিওএমের জন্য)। অবজেক্টটি কেবল জেএস অবজেক্টের জন্য যা আমার মনে পড়ে for
হেলবাবি

2
@ হেলবাবি এই প্রশ্নটি ভেরিয়েবল সম্পর্কে - ডিওএম নয়।
বেনিয়ামিন গ্রুইনবাউম

9
বেনজামিন গ্রুয়েনবাউম বিকাশকারী.মোজিলা.আর. / ইউ- ইউএস / ডকস / ওয়েবে / জাভা স্ক্রিপ্ট / রেফারেন্স / এর মতে @ অবজেক্ট.ওবিজারটি অপ্রচলিত বা অবহেলিত। প্রস্তাবিত প্রতিস্থাপন (একই পৃষ্ঠায় প্রতিটি) প্রক্সি অবজেক্ট।
stannius

4
প্রশ্নটি শুধুমাত্র সম্পর্কে জিজ্ঞাসা করছে variable, তবুও এখানে সমস্ত উত্তর উল্লেখ করা হয়েছে property। আমি যদি আমরা local variableপরিবর্তনগুলি শুনতে পারি তবে অবাক হই ।
থারিক নগ্রোহোতোমো

1
এর কোন উত্তর আছে কি? আমার অর্থ, একটি নির্বাচন করতে
ব্রায়ান মেলর

উত্তর:


100

হ্যাঁ, এটি এখন সম্পূর্ণ সম্ভব!

আমি জানি এটি একটি পুরানো থ্রেড তবে এখন এ্যাক্সেসরগুলি (গেটার্স এবং সেটটার) ব্যবহার করে এটি সম্ভব: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters

আপনি এই জাতীয় কোনও বিষয়টিকে সংজ্ঞায়িত করতে পারেন, aInternalএতে ক্ষেত্রটি উপস্থাপন করে a:

x = {
  aInternal: 10,
  aListener: function(val) {},
  set a(val) {
    this.aInternal = val;
    this.aListener(val);
  },
  get a() {
    return this.aInternal;
  },
  registerListener: function(listener) {
    this.aListener = listener;
  }
}

তারপরে আপনি নিম্নলিখিতটি ব্যবহার করে শ্রোতার নিবন্ধন করতে পারেন:

x.registerListener(function(val) {
  alert("Someone changed the value of x.a to " + val);
});

সুতরাং যখনই কোনও কিছুর মান পরিবর্তন হয় x.a, শ্রোতার ফাংশনটি বরখাস্ত করা হবে। নিম্নলিখিত লাইনটি চালানো সতর্কতা পপআপ এনে দেবে:

x.a = 42;

এখানে একটি উদাহরণ দেখুন: https://jsfiddle.net/5o1wf1bn/1/

আপনি একক শ্রোতার স্লটের পরিবর্তে শ্রোতার একটি অ্যারে ব্যবহার করতে পারেন, তবে আমি আপনাকে সবচেয়ে সহজ সম্ভাব্য উদাহরণটি দিতে চাইছিলাম।


6
এটি প্রতি বস্তুর জন্য একটি টন কোড, এটি আরও পুনরায় ব্যবহারযোগ্য করার কোনও উপায় আছে?
ওয়েল ভিক্টাস

আপনার কোড কোথায়? আপনি এটি থেকে একটি নতুন প্রশ্ন শুরু করেছেন?
আকিরা

কোনও বস্তুতে যখন নতুন সম্পত্তি যুক্ত করা হয়েছে, বা একটি সরানো হয়েছে তখন সনাক্ত করার উপায় সম্পর্কে কী বলা যায়?
মাইকেল

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

1
আপনার কেবলমাত্র একটি এককের পরিবর্তে শ্রোতার একটি অ্যারে থাকা প্রয়োজন এবং তারপরে কেবল কল করার পরিবর্তে this.aListener(val), আপনাকে সমস্ত শ্রোতার ফাংশনটি লুপ করতে হবে এবং প্রতিটিকে পাসিং করতে হবে val। সাধারণত, পদ্ধতিটির addListenerপরিবর্তে বলা হয় registerListener
আকিরা

74

এই প্রশ্নের বেশিরভাগ উত্তর হয় পুরানো, অকার্যকর, বা বড় ফোলা গ্রন্থাগারগুলির অন্তর্ভুক্তির প্রয়োজন:

আজ, আপনি এখন কোনও সামগ্রীতে করা পরিবর্তনগুলি (এবং ইন্টারসেপ্ট) পর্যবেক্ষণ করতে প্রক্সি অবজেক্টটি ব্যবহার করতে পারেন । ওপি যা করার চেষ্টা করছে তার জন্য এটি নির্মিত। এখানে একটি প্রাথমিক উদাহরণ:

var targetObj = {};
var targetProxy = new Proxy(targetObj, {
  set: function (target, key, value) {
      console.log(`${key} set to ${value}`);
      target[key] = value;
      return true;
  }
});

targetProxy.hello_world = "test"; // console: 'hello_world set to test'

Proxyঅবজেক্টের একমাত্র ত্রুটিগুলি :

  1. Proxyবস্তু (যেমন IE11 হিসাবে) পুরোনো ব্রাউজারে পাওয়া যায় না এবং polyfill সম্পূর্ণরূপে প্রতিলিপি করতে পারেন না Proxyকার্যকারিতা।
  2. প্রক্সি অবজেক্টগুলি সর্বদা বিশেষ বস্তুর (যেমন, Date) প্রত্যাশার সাথে আচরণ করে না - Proxyবস্তুটি সাদামাটা অবজেক্টস বা অ্যারেগুলির সাথে সর্বোত্তমভাবে যুক্ত হয়।

যদি আপনার কোনও নেস্টেড অবজেক্টে করা পরিবর্তনগুলি পর্যবেক্ষণ করতে হয় , তবে আপনাকে পর্যবেক্ষণযোগ্য স্লিম (যা আমি প্রকাশ করেছি) এর মতো বিশেষায়িত লাইব্রেরি ব্যবহার করতে হবে যা এই জাতীয় কাজ করে:

var test = {testing:{}};
var p = ObservableSlim.create(test, true, function(changes) {
    console.log(JSON.stringify(changes));
});

p.testing.blah = 42; // console:  [{"type":"add","target":{"blah":42},"property":"blah","newValue":42,"currentPath":"testing.blah",jsonPointer:"/testing/blah","proxy":{"blah":42}}]

1
আমি আরও একটি অপূর্ণতা যুক্ত করব, আপনি আসলে লক্ষ্য অবজেক্টে পরিবর্তনগুলি দেখেন না কেবল কেবল প্রক্সি অবজেক্টে। কিছু ক্ষেত্রে, আপনি কেবলমাত্র জানতে চান কখন লক্ষ্য বস্তুতে (যেমন target.hello_world = "test") কোনও সম্পত্তি পরিবর্তন হয়
ক্রিশ্চিয়ানো

2
you don't actually watch changes on the target object but only on proxy object- এটা ঠিক সঠিক নয়। Proxyবস্তু পরিবর্তিত নয় - এটা লক্ষ্য এটা নিজস্ব কপি নেই। you just want to know when a property change on the target object- আপনি এটির মাধ্যমে এটি সম্পাদন করতে পারেন Proxy, প্রক্সিগুলির জন্য এটি প্রাথমিক ব্যবহারের ক্ষেত্রে অন্যতম।
এলিয়ট বি।

2
না, কারণ আপনি সরাসরি লক্ষ্যটি পরিবর্তন করছেন। আপনি যদি পরিবর্তনটি পর্যবেক্ষণ করতে চান targetতবে আপনাকে এটি একটি প্রক্সি দিয়ে করতে হবে। তবে এর proxy.hello_world = "test"অর্থ এই নয় যে আপনি প্রক্সিটি সংশোধন করছেন, প্রক্সিটি অপরিবর্তিত রয়েছে, targetপরিবর্তিত হবে (যদি আপনার সেট হ্যান্ডলারটি এটির জন্য কনফিগার করা থাকে)। আপনার মতামতটি মনে হচ্ছে আপনি সরাসরি পর্যবেক্ষণ করতে পারবেন না target.hello_world = "test"। ঐটা সত্য. সরল ভেরিয়েবল অ্যাসাইনমেন্ট কোনও ধরণের ইভেন্ট নির্গত হয় না। এজন্য আমাদের এই প্রশ্নের উত্তরে বর্ণিত মত সরঞ্জামগুলি ব্যবহার করতে হবে।
ইলিয়ট বি।

2
আপনাকে ধন্যবাদ এলিয়ট বি। It sounds like your point is that you cannot directly observe target.hello_world = "test". That is true.এটাই আমার বক্তব্য। আমার ক্ষেত্রে আমার কাছে অন্য কোনও আইটেম তৈরি হয়েছে এবং অন্য কোনও কোড দ্বারা এটি আপডেট হয়েছে ... একটি প্রক্সি, এই ক্ষেত্রে কার্যকর নয়, কারণ পরিবর্তনগুলি লক্ষ্যমাত্রায় করা হবে।
ক্রিশ্চিয়ানো

1
@ ক্রিশ্চিয়ানো আমি অনুমান করি এলিয়ট যা বলার চেষ্টা করছে তা হ'ল আপনি প্রকৃত বস্তুর পরিবর্তে প্রক্সিটি ব্যবহার করতে পারবেন , এর অর্থ আপনি যদি এটির মতো আপনার প্রক্সিটির সাথে প্রক্সিটি পাস করতে পারেন এবং অ্যাপের অন্যান্য অংশগুলি আপনার প্রক্সিটির সাথে ইন্টারেক্ট করতে পারেন make প্রক্সি পরিবর্তনগুলি প্রকৃত বস্তুর প্রতিফলিত হবে।
জোল্টন ম্যাটেক

33

না।

তবে, যদি এটি সত্যিই গুরুত্বপূর্ণ হয় তবে আপনার কাছে দুটি বিকল্প রয়েছে (প্রথম পরীক্ষা করা হচ্ছে, দ্বিতীয়টি নয়):

প্রথমে সেটার এবং গেটার ব্যবহার করুন, এর মতো:

var myobj = {a : 1};

function create_gets_sets(obj) { // make this a framework/global function
    var proxy = {}
    for ( var i in obj ) {
        if (obj.hasOwnProperty(i)) {
            var k = i;
            proxy["set_"+i] = function (val) { this[k] = val; };
            proxy["get_"+i] = function ()    { return this[k]; };
        }
    }
    for (var i in proxy) {
        if (proxy.hasOwnProperty(i)) {
            obj[i] = proxy[i];
        }
    }
}

create_gets_sets(myobj);

তাহলে আপনি এর মতো কিছু করতে পারেন:

function listen_to(obj, prop, handler) {
    var current_setter = obj["set_" + prop];
    var old_val = obj["get_" + prop]();
    obj["set_" + prop] = function(val) { current_setter.apply(obj, [old_val, val]); handler(val));
}

তারপরে শ্রোতাদের মতো করুন:

listen_to(myobj, "a", function(oldval, newval) {
    alert("old : " + oldval + " new : " + newval);
}

দ্বিতীয়ত, আমি আসলে ভুলে গেছি, আমি যখন এটির কথা ভাবব তখনই জমা দেব :)

সম্পাদনা: ওহ, আমার মনে আছে :) আপনি মানটির উপর নজর রাখতে পারেন:

উপরে মওবজ দেওয়া হয়েছে, এটিতে 'এ' দিয়ে:

function watch(obj, prop, handler) { // make this a framework/global function
    var currval = obj[prop];
    function callback() {
        if (obj[prop] != currval) {
            var temp = currval;
            currval = obj[prop];
            handler(temp, currval);
        }
    }
    return callback;
}

var myhandler = function (oldval, newval) {
    //do something
};

var intervalH = setInterval(watch(myobj, "a", myhandler), 100);

myobj.set_a(2);

8
"দেখছেন" আসলে একটি পরিবর্তন সনাক্ত করছে না। এটি ইভেন্ট ভিত্তিক নয় এবং খুব শীঘ্রই খুব সহজেই পুরো অ্যাপটি ধীর করে দেবে। এই পদ্ধতির আইএমএইচও কখনই বাস্তব প্রকল্পের অংশ হওয়া উচিত নয়।
মুহাম্মদ বিন ইউসরাত

28

ব্যবহার Prototype: https://developer.mozilla.org/en-US/docs/Web/JavaScript/ উল্লেখ / গ্লোবাল_অবজেক্টস / অবজেক্ট / ডিফাইনপ্রোপার্টি

// Console
function print(t) {
  var c = document.getElementById('console');
  c.innerHTML = c.innerHTML + '<br />' + t;
}

// Demo
var myVar = 123;

Object.defineProperty(this, 'varWatch', {
  get: function () { return myVar; },
  set: function (v) {
    myVar = v;
    print('Value changed! New value: ' + v);
  }
});

print(varWatch);
varWatch = 456;
print(varWatch);
<pre id="console">
</pre>

অন্য উদাহরণ

// Console
function print(t) {
  var c = document.getElementById('console');
  c.innerHTML = c.innerHTML + '<br />' + t;
}

// Demo
var varw = (function (context) {
  return function (varName, varValue) {
    var value = varValue;
  
    Object.defineProperty(context, varName, {
      get: function () { return value; },
      set: function (v) {
        value = v;
        print('Value changed! New value: ' + value);
      }
    });
  };
})(window);

varw('varWatch'); // Declare
print(varWatch);
varWatch = 456;
print(varWatch);

print('---');

varw('otherVarWatch', 123); // Declare with initial value
print(otherVarWatch);
otherVarWatch = 789;
print(otherVarWatch);
<pre id="console">
</pre>


দ্বিতীয় উদাহরণটি কিছুটা বিভ্রান্তিকর, varw২ টি যুক্তি প্রয়োজন তবে আপনার উদাহরণের অংশটি দেখায় যে ফাংশনটি কেবলমাত্র মান প্যারামিটার দিয়ে ডাকা হচ্ছে।
হালাউলেকা এমএএস

22

একটি পুরানো থ্রেড আনার জন্য দুঃখিত, তবে যারা (আমার মত!) এলি গ্রে-র উদাহরণটি কীভাবে কাজ করে তা দেখতে পান না তাদের জন্য এখানে একটি সামান্য ম্যানুয়াল দেওয়া আছে:

var test = new Object();
test.watch("elem", function(prop,oldval,newval){
    //Your code
    return newval;
});

আশা করি এটি কারও সাহায্য করতে পারে


9
এই মুহুর্তে ক্রোম বা সাফারিতে ওয়াচ সমর্থিত নয়, কেবল ফায়ারফক্স
পল ম্যাকক্লিয়ান

5
প্রতি মজিলা বিকাশকারী নেটওয়ার্ক, এটির প্রস্তাব দেওয়া হয় না। অবজেক্ট.প্রোটোটাইপ.ওয়াচ () কেবলমাত্র পরীক্ষার জন্য তৈরি হয়েছিল এবং এটি উত্পাদন কোডে ব্যবহার করা উচিত নয়। বিকাশকারী.মোজিলা.আর.ইন-
ডেনিস বার্টলেট

4
@ পলম্যাকক্লিয়েন এই উত্তরটি এলি গ্রেয়ের উত্তরের প্রতিক্রিয়াতে ছিল যার একটি পলিফিল রয়েছে। gist.github.com/eligrey/384583
hobbyist

2
মোজিলা কর্তৃক ঘড়িটি হ্রাস করা হয়েছে। এই উত্তর বিভ্রান্তিকর হতে পারে।
আরনৌদ

7

লুক স্কাফারের উত্তর হিসাবে ( দ্রষ্টব্য : এটি তার মূল পোস্টকে বোঝায়; তবে এখানে পুরো পয়েন্টটি সম্পাদনার পরে বৈধ থাকবে ), আপনার মানটি অ্যাক্সেস করার জন্য আমি গেট / সেট পদ্ধতিগুলির একটি জুড়িও প্রস্তাব করব।

তবে আমি কিছু পরিবর্তন প্রস্তাব করব (এবং এজন্য আমি পোস্ট করছি ...)।

এই কোডটির সাথে একটি সমস্যা হ'ল aঅবজেক্টের ক্ষেত্রটি myobjসরাসরি অ্যাক্সেসযোগ্য, তাই শ্রোতাদের ট্রিগার না করেই এটির অ্যাক্সেস করা / তার মান পরিবর্তন করা সম্ভব:

var myobj = { a : 5, get_a : function() { return this.a;}, set_a : function(val) { this.a = val; }}
/* add listeners ... */
myobj.a = 10; // no listeners called!

encapsulation

সুতরাং, শ্রোতাদের প্রকৃতপক্ষে ডেকে আনা গ্যারান্টিটি দেওয়ার জন্য, আমাদের সেই ক্ষেত্রে সরাসরি প্রবেশ করতে নিষেধ করতে হবে a। কীভাবে করবেন? একটি বন্ধ ব্যবহার করুন !

var myobj = (function() { // Anonymous function to create scope.

    var a = 5;            // 'a' is local to this function
                          // and cannot be directly accessed from outside
                          // this anonymous function's scope

    return {
        get_a : function() { return a; },   // These functions are closures:
        set_a : function(val) { a = val; }  // they keep reference to
                                            // something ('a') that was on scope
                                            // where they were defined
    };
})();

এখন আপনি লুকের প্রস্তাব অনুসারে শ্রোতাদের তৈরি এবং যুক্ত করতে একই পদ্ধতি ব্যবহার করতে পারেন তবে আপনি আশ্বস্ত হয়ে থাকতে পারেন যে পড়ার বা aমনোযোগবিহীন হয়ে লেখার কোনও সম্ভাব্য উপায় নেই !

প্রোগ্রামগতভাবে এনক্যাপসুলেটেড ক্ষেত্রগুলি যুক্ত করা হচ্ছে

তবুও লুকের ট্র্যাকে, আমি এখন একটি সহজ ফাংশন কলের মাধ্যমে এনক্যাপসুলেটেড ক্ষেত্রগুলি এবং সম্পর্কিত গিটার / সেটটারগুলিকে বস্তুগুলিতে যুক্ত করার একটি সহজ উপায় প্রস্তাব করছি।

নোট করুন যে এটি শুধুমাত্র মান ধরণের সাথে সঠিকভাবে কাজ করবে । সঙ্গে এটির জন্য কাজ করতে রেফারেন্স ধরনের , এক ধরনের গভীর কপি বাস্তবায়ন হবে (দেখুন থাকবে এই এক , উদাহরণস্বরূপ)।

function addProperty(obj, name, initial) {
    var field = initial;
    obj["get_" + name] = function() { return field; }
    obj["set_" + name] = function(val) { field = val; }
}

এটি আগের মতোই কাজ করে: আমরা একটি ফাংশনে একটি স্থানীয় ভেরিয়েবল তৈরি করি এবং তারপরে আমরা একটি ক্লোজার তৈরি করি।

এটি কিভাবে ব্যবহার করতে? সরল:

var myobj = {};
addProperty(myobj, "total", 0);
window.alert(myobj.get_total() == 0);
myobj.set_total(10);
window.alert(myobj.get_total() == 10);

2
এনক্যাপসুলেশনের জন্য +1। এটি আমার প্রথম চিন্তা ছিল, তবে আমি শেষ পর্যন্ত ক্রিয়েটিজেটসেটস পদ্ধতি যুক্ত করার সক্ষমতা চেয়েছিলাম এবং যেহেতু এটি নির্বিচারে, তাই মানগুলি আড়াল করা ভাল নয় :) আমরা এটিকে আরও একধাপ এগিয়ে নিয়ে যেতে এবং মানগুলি আড়াল করার জন্য কিছু লিখতে পারি, তবে আমার মনে হয় আমি পোস্ট করা কোডটি বেশিরভাগ মানুষের পক্ষে যথেষ্ট বিভ্রান্তিকর ... এটির জন্য যদি কোনও কল আসতে পারে ...
লুক স্ক্যাফার

6

আপনি যদি jQuery {UI using (যা প্রত্যেকের ব্যবহার করা উচিত :-)) ব্যবহার করেন তবে আপনি একটি লুকানো <ইনপুট /> উপাদান দিয়ে। পরিবর্তন () ব্যবহার করতে পারেন।


7
আমি বেশ বুঝতে পারি না। আপনি কীভাবে কোনও লুকানো <input/>উপাদানের সাথে ভেরিয়েবল সংযুক্ত করতে পারেন ?
পিটার লি

4
আমি মনে করি চক পরামর্শ দিচ্ছে যে আপনি jquery ব্যবহার করে ইনপুটটির মান সেট করতে পারেন এবং তারপরে এবং একটি পরিবর্তন () ইভেন্ট শ্রোতা। যদি আপনি .val () দিয়ে ইনপুটটির মান আপডেট করেন তবে। পরিবর্তন () ইভেন্ট কলব্যাকটি আগুনে ফেলা হবে।
jareeraj

2
<input type="hidden" value="" id="thisOne" />এবং jQuery সঙ্গে $("#thisOne").change(function() { do stuff here });এবং $("#thisOne").val(myVariableWhichIsNew);এবং তারপর .change()ইচ্ছার আগুন।
খভেরিম

2
এটি আমার বইগুলির সেরা সমাধান। সহজ, সহজ। আপনার কোডে ভেরিয়েবল পরিবর্তন করার পরিবর্তে var1 = 'new value';, আপনি পরিবর্তে এই লুকানো ইনপুটটির মান নির্ধারণ করবেন, তারপরে ভেরিয়েবলটি পরিবর্তন করতে একটি শ্রোতা যুক্ত করুন। $("#val1").on('change', function(){ val1 = this.val(); ... do the stuff that you wanted to do when val1 changed... }); $("#val1").val('new value');
টম ওয়াকার 21

2
আমার মতো একই সমস্যার যে কারও জন্য, যদি পরিবর্তন ইভেন্টটি ট্রিগার না করে তবে $ ("# এটিই")। ভাল (মাইভ্যারেটিওয়াইচআইএসনিউ)। ট্রিগার ('পরিবর্তন')
H

6

AngularJS(আমি জানি এটি নয় JQuery, তবে এটি সাহায্য করতে পারে [[খাঁটি জেএস কেবলমাত্র তত্ত্বের ক্ষেত্রে ভাল)):

$scope.$watch('data', function(newValue) { ..

যেখানে "ডেটা" স্কোপটিতে আপনার পরিবর্তনশীলটির নাম।

দস্তাবেজের একটি লিঙ্ক আছে।


দুর্ভাগ্যক্রমে এটি আপনাকে পরিবর্তনকে স্কোপে বাঁধতে বাধ্য করে
রুक्स

এটি তখনই চালিত হয় যখন $scope.$apply()চালানো হয়
iamawebgeek

5

কয়েক বছর পরে যারা সুরের জন্য:

বেশিরভাগ ব্রাউজারের (এবং আই 6 +) এর জন্য একটি সমাধান পাওয়া যায় যা অনপ্রোটার্টিচেঞ্জ ইভেন্ট এবং নতুনতর বৈশিষ্ট্য সংজ্ঞায়িত প্রোপার্টি ব্যবহার করে। সামান্য ক্যাচটি হ'ল আপনাকে আপনার ভেরিয়েবলটিকে একটি ডোম অবজেক্ট তৈরি করতে হবে।

সম্পূর্ণ তথ্যাদি:

http://johndyer.name/native-browser-get-set-properties-in-javascript/


3

আপনি যে কার্যকারিতাটি সন্ধান করছেন তা "DefineProperty ()" পদ্ধতির ব্যবহারের মাধ্যমে অর্জন করা যেতে পারে - যা কেবলমাত্র আধুনিক ব্রাউজারগুলিতেই উপলভ্য:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

আমি একটি jQuery এক্সটেনশন লিখেছি যা আপনার যদি আরও ক্রস ব্রাউজার সমর্থনের প্রয়োজন হয় তবে কিছু অনুরূপ কার্যকারিতা রয়েছে:

https://github.com/jarederaj/jQueue

একটি ছোট jQuery এক্সটেনশান যা ভেরিয়েবল, অবজেক্ট বা কী এর অস্তিত্বের জন্য কুইউন্ডিং কলব্যাকগুলি পরিচালনা করে। আপনি ব্যাকগ্রাউন্ডে চলমান প্রক্রিয়াগুলির দ্বারা প্রভাবিত হতে পারে এমন কোনও ডেটা পয়েন্টের যে কোনও সংখ্যক কলব্যাক বরাদ্দ করতে পারেন। jQueue আপনার অস্তিত্বের জন্য নির্দিষ্ট হওয়া এই ডেটাগুলি শোনার জন্য অপেক্ষা করে এবং তার যুক্তি সহ সঠিক কলব্যাক বন্ধ করে দেয়।


2

সরাসরি নয়: আপনার কোনও জোড়ের "অ্যাডলিস্টার / রিমললিস্টনার" ইন্টারফেসের সাথে একটি জু গিটার / সেটার প্রয়োজন ... বা একটি এনপিএপিআই প্লাগইন (তবে এটি সম্পূর্ণ অন্য গল্প)।


1
//ex:
/*
var x1 = {currentStatus:undefined};
your need is x1.currentStatus value is change trigger event ?
below the code is use try it.
*/
function statusChange(){
    console.log("x1.currentStatus_value_is_changed"+x1.eventCurrentStatus);
};

var x1 = {
    eventCurrentStatus:undefined,
    get currentStatus(){
        return this.eventCurrentStatus;
    },
    set currentStatus(val){
        this.eventCurrentStatus=val;
      //your function();
    }
};

অথবা

/*  var x1 = {
eventCurrentStatus:undefined,
currentStatus : {
    get : function(){
        return Events.eventCurrentStatus
        },
    set : function(status){
        Events.eventCurrentStatus=status;

    },
}*/
console.log("eventCurrentStatus = "+ x1.eventCurrentStatus);
x1.currentStatus="create"
console.log("eventCurrentStatus = "+ x1.eventCurrentStatus);
x1.currentStatus="edit"
console.log("eventCurrentStatus = "+ x1.eventCurrentStatus);
console.log("currentStatus = "+ x1.currentStatus);

অথবা

/* global variable ku*/
    var jsVarEvents={};
    Object.defineProperty(window, "globalvar1", {//no i18n
        get: function() { return window.jsVarEvents.globalvarTemp},
        set: function(value) { window.window.jsVarEvents.globalvarTemp = value; }
    });
    console.log(globalvar1);
    globalvar1=1;
    console.log(globalvar1);

1

একটি বরং সহজ এবং সরল সমাধান হ'ল গ্লোবাল ভেরিয়েবলের মান নির্ধারণের জন্য কেবল একটি ফাংশন কল ব্যবহার করা এবং এর মানটি কখনও সরাসরি সেট না করা। এইভাবে আপনার সম্পূর্ণ নিয়ন্ত্রণ রয়েছে:

var globalVar;

function setGlobalVar(value) {
    globalVar = value;
    console.log("Value of globalVar set to: " + globalVar);
    //Whatever else
}

এটি প্রয়োগের কোনও উপায় নেই, এটির জন্য কেবল প্রোগ্রামিং শৃঙ্খলা দরকার ... যদিও আপনি grep(বা অনুরূপ কিছু) ব্যবহার করতে পারেন তা পরীক্ষা করে দেখতে পারেন যে আপনার কোডটি সরাসরি কোথাও মান নির্ধারণ করে না doesglobalVar

অথবা আপনি এটি কোনও অবজেক্ট এবং ব্যবহারকারী গিটার এবং সেটার পদ্ধতিতে সজ্জিত করতে পারেন ... কেবল একটি চিন্তা।


কোনও ভেরিয়েবলের জন্য যা কোনও সামগ্রীর সম্পত্তি নয় সেগুলি অ্যাক্সেস করতে পারে - যেমনটি varES6 মডিউলগুলিতে ঘোষিত ভেরিয়েবলগুলির ক্ষেত্রে - এটিই একমাত্র সমাধান।
amn

1

দয়া করে ছেলেরা মনে রাখবেন প্রাথমিক প্রশ্নটি ভারিবেলসের জন্য ছিল, ওবিজেসিটিসের জন্য নয়;)

উপরের সমস্ত উত্তর ছাড়াও, আমি forWatch.js নামে একটি ক্ষুদ্র লিব তৈরি করেছি , যা জাভাস্ক্রিপ্টে সাধারণ গ্লোবাল ভেরিয়েবলের পরিবর্তনের জন্য একইভাবে ধরতে এবং কলব্যাক করতে ব্যবহার করে।

জ্যাকুরি ভেরিয়েবলের সাথে সামঞ্জস্যপূর্ণ, ওবিজেইসিটিএস ব্যবহার করার দরকার নেই এবং প্রয়োজনে আপনি সরাসরি বেশ কয়েকটি ভেরিয়েবলের একটি অ্যারে পাস করতে পারেন।

যদি এটি সহায়ক হতে পারে ...: https://bitbucket.org/esabora/forthewatch
মূলত আপনাকে কেবল ফাংশনটি কল করতে হবে:
watchIt("theVariableToWatch", "varChangedFunctionCallback");

প্রাসঙ্গিক না হলে এবং অগ্রিম দুঃখিত।


1

এই উত্তরটি থেকে শুরু করে আমি সবচেয়ে সহজ উপায় :

// variable holding your data
const state = {
  count: null,
  update() {
    console.log(`this gets called and your value is ${this.pageNumber}`);
  },
  get pageNumber() {
    return this.count;
  },
  set pageNumber(pageNumber) {
    this.count = pageNumber;
    // here you call the code you need
    this.update(this.count);
  }
};

এবং তারপর:

state.pageNumber = 0;
// watch the console

state.pageNumber = 15;
// watch the console

1

আমার ক্ষেত্রে, আমি আমার প্রকল্পে অন্তর্ভুক্ত থাকা কোনও লাইব্রেরি আমার নতুন সংজ্ঞা দিচ্ছিল কিনা তা অনুসন্ধান করার চেষ্টা করছিলাম window.player। সুতরাং, আমার কোডের সূচনাতে, আমি সবেমাত্র করেছি:

Object.defineProperty(window, 'player', {
  get: () => this._player,
  set: v => {
    console.log('window.player has been redefined!');
    this._player = v;
  }
});

0

এটি সরাসরি সম্ভব নয়।

তবে এটি কাস্টমএভেন্ট ব্যবহার করে করা যেতে পারে: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent

নীচের পদ্ধতিটি একটি ইনপুট হিসাবে ভেরিয়েবল নামের একটি অ্যারে গ্রহণ করে এবং প্রতিটি ভেরিয়েবলের জন্য ইভেন্ট শ্রোতাদের যুক্ত করে এবং ভেরিয়েবলের মানটিতে কোনও পরিবর্তনের জন্য ইভেন্টটিকে ট্রিগার করে।

মানটি পরিবর্তনটি সনাক্ত করার জন্য পদ্ধতিটি ভোটদান ব্যবহার করে। আপনি সময়কালীন সময়টির জন্য মিলি সেকেন্ডে মান বাড়িয়ে দিতে পারেন।

function watchVariable(varsToWatch) {
    let timeout = 1000;
    let localCopyForVars = {};
    let pollForChange = function () {
        for (let varToWatch of varsToWatch) {
            if (localCopyForVars[varToWatch] !== window[varToWatch]) {
                let event = new CustomEvent('onVar_' + varToWatch + 'Change', {
                    detail: {
                        name: varToWatch,
                        oldValue: localCopyForVars[varToWatch],
                        newValue: window[varToWatch]
                    }
                });
                document.dispatchEvent(event);
                localCopyForVars[varToWatch] = window[varToWatch];
            }
        }
        setTimeout(pollForChange, timeout);
    };
    let respondToNewValue = function (varData) {
        console.log("The value of the variable " + varData.name + " has been Changed from " + varData.oldValue + " to " + varData.newValue + "!!!"); 
    }
    for (let varToWatch of varsToWatch) {
        localCopyForVars[varToWatch] = window[varToWatch];
        document.addEventListener('onVar_' + varToWatch + 'Change', function (e) {
            respondToNewValue(e.detail);
        });
    }
    setTimeout(pollForChange, timeout);
}

পদ্ধতিটি কল করে:

watchVariables(['username', 'userid']);

এটি ভেরিয়েবলের ব্যবহারকারীর নাম এবং ব্যবহারকারীর পরিবর্তনগুলি সনাক্ত করবে।


0

সাহায্যে সংগ্রহকারী এবং সেটার , আপনি একটি জাভাস্ক্রিপ্ট বর্গ যে এই ধরনের একটা জিনিস আছে বর্ণনা করতে পারেন।

প্রথমত, আমরা আমাদের ক্লাস নামক সংজ্ঞায়িত করি MonitoredVariable:

class MonitoredVariable {
  constructor(initialValue) {
    this._innerValue = initialValue;
    this.beforeSet = (newValue, oldValue) => {};
    this.beforeChange = (newValue, oldValue) => {};
    this.afterChange = (newValue, oldValue) => {};
    this.afterSet = (newValue, oldValue) => {};
  }

  set val(newValue) {
    const oldValue = this._innerValue;
    // newValue, oldValue may be the same
    this.beforeSet(newValue, oldValue);
    if (oldValue !== newValue) {
      this.beforeChange(newValue, oldValue);
      this._innerValue = newValue;
      this.afterChange(newValue, oldValue);
    }
    // newValue, oldValue may be the same
    this.afterSet(newValue, oldValue);
  }

  get val() {
    return this._innerValue;
  }
}

ধরে নিন যে আমরা moneyপরিবর্তনগুলি শুনতে চাই , আসুন MonitoredVariableপ্রাথমিক অর্থ দিয়ে একটি উদাহরণ তৈরি করুন 0:

const money = new MonitoredVariable(0);

তারপরে আমরা এর মানটি পেতে বা এটি নির্ধারণ করতে পারতাম money.val:

console.log(money.val); // Get its value
money.val = 2; // Set its value

যেহেতু আমরা এর জন্য কোনও শ্রোতাকে সংজ্ঞায়িত করি নি, তাই money.val2 এ পরিবর্তনের পরে বিশেষ কিছু হয় না ।

এখন কিছু শ্রোতার সংজ্ঞা দেওয়া যাক। আমরা চার শ্রোতাকে প্রাপ্তিসাধ্য আছে: beforeSet, beforeChange, afterChange, afterSet। আপনি যখন money.val = newValueভেরিয়েবলের মান পরিবর্তন করতে ব্যবহার করেন তবে নিম্নলিখিতটি ক্রমানুসারে ঘটবে :

  1. Money.beforeSet (newValue, oldValue);
  2. Money.beforeChange (newValue, oldValue); (যদি এর মান পরিবর্তন না করা হয় তবে এড়ানো হবে)
  3. টাকা.ভাল = newValue;
  4. টাকা। (যদি এর মান পরিবর্তন না করা হয় তবে এড়ানো হবে)
  5. মানি.এফটারসেট (নিউভ্যালু, ওল্ডভ্যালু);

এখন আমরা afterChangeশ্রোতাদের সংজ্ঞা দিই যা money.valপরিবর্তিত হওয়ার পরেই ট্রিগার করা afterSetহবে (যখন নতুন মানটি পুরানোটির সমান হয় তবুও ট্রিগার হবে):

money.afterChange = (newValue, oldValue) => {
  console.log(`Money has been changed from ${oldValue} to ${newValue}`);
};

এখন একটি নতুন মান সেট করুন 3এবং দেখুন কি ঘটে:

money.val = 3;

আপনি কনসোলে নিম্নলিখিতগুলি দেখতে পাবেন:

Money has been changed from 2 to 3

পূর্ণ কোডের জন্য, https://gist.github.com/yusanshi/65745acd23c8587236c50e54f25731ab দেখুন


-2

এটি একটি পুরানো থ্রেড তবে আমি কৌণিক ব্যবহার করে সমাধানের সন্ধান করতে গিয়ে দ্বিতীয় সর্বোচ্চ উত্তরের (কাস্টম শ্রোতার) কাছে হোঁচট খেয়েছি। সমাধানটি কাজ করার সময়, কৌণিকের এটি @Outputএবং ইভেন্ট ইমিটারগুলি ব্যবহার করে এটি সমাধান করার জন্য আরও ভাল নির্মিত built কাস্টম শ্রোতার উত্তরে উদাহরণটি বাদ দেওয়া:

ChildComponent.html

<button (click)="increment(1)">Increment</button>

ChildComponent.ts

import {EventEmitter, Output } from '@angular/core';

@Output() myEmitter: EventEmitter<number> = new EventEmitter<number>();

private myValue: number = 0;

public increment(n: number){
  this.myValue += n;

  // Send a change event to the emitter
  this.myEmitter.emit(this.myValue);
}

ParentComponent.html

<child-component (myEmitter)="monitorChanges($event)"></child-component>
<br/>
<label>{{n}}</label>

ParentComponent.ts

public n: number = 0;

public monitorChanges(n: number){
  this.n = n;
  console.log(n);
}

nচাইল্ড বোতামটি ক্লিক করার পরে এটি এখন পিতামাতার কাছে আপডেট হবে । স্ট্যাকব্লিটজ কাজ করছে


-3
Utils = {
    eventRegister_globalVariable : function(variableName,handlers){
        eventRegister_JsonVariable(this,variableName,handlers);
    },
    eventRegister_jsonVariable : function(jsonObj,variableName,handlers){
        if(jsonObj.eventRegisteredVariable === undefined) {
            jsonObj.eventRegisteredVariable={};//this Object is used for trigger event in javascript variable value changes ku
        }
        Object.defineProperty(jsonObj, variableName , {
                    get: function() { 
                        return jsonObj.eventRegisteredVariable[variableName] },
                    set: function(value) {
                        jsonObj.eventRegisteredVariable[variableName] = value; handlers(jsonObj.eventRegisteredVariable[variableName]);}
                    });
            }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.