Прослуховування змінних змін у JavaScript


462

Чи можлива подія в JS, яка запускається, коли значення певної змінної змінюється? JQuery прийнято.


@BenjaminGruenbaum, напевно, ви хочете сказати MutableObserver (для DOM). Об'єкт лише для об'єктів JS з того, що я пам’ятаю.
HellBaby

2
@HellBaby Це питання стосується змінних, а не DOM.
Бенджамін Грюнбаум

9
@BenjaminGruenbaum за версією developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Object.observe застарілий або застарілий. Рекомендована заміна (на тій самій сторінці) є об'єктом проксі.
stannius

4
Питання, про яке тільки задається variable, але всі відповіді тут стосуються property. Цікаво, чи ми можемо прислухатися до local variableзмін.
Thariq Nugrohotomo

1
чи є на це відповідь? Я маю на увазі вибрати один
Брайан Меллор

Відповіді:


100

Так, це зараз цілком можливо!

Я знаю, що це стара тема, але тепер цей ефект можливий за допомогою аксесуарів (getters і setters): 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
Це тонна коду на об'єкт, чи є спосіб зробити це більш багаторазовим?
Vael Victus

Де ваш код? Ви почали з нього нове запитання?
Акіра

Як щодо способу виявлення, коли до об’єкту додано нове властивість чи його видалено?
Майкл

Це стара відповідь, але я хотів додати, що це добре працює для значень масиву, а також поки ви встановлюєте значення масиву замість того, щоб на нього натискати.
TabsNotSpaces

1
Вам просто потрібно мати масив слухачів замість одного, а потім замість того, щоб просто дзвонити this.aListener(val), вам доведеться переглядати всі функції слухача і зателефонувати кожному, хто проходить val. Зазвичай метод називається addListenerзамість registerListener.
Акіра

74

Більшість відповідей на це питання або застарілі, неефективні, або потребують включення великих роздутих бібліотек:

  • Object.watch і Object.observe як застарілі, так і не повинні використовуватися.
  • onPropertyChange - обробник подій елементів DOM, який працює лише в деяких версіях IE.
  • Object.defineProperty дозволяє зробити властивість об'єкта незмінною, що дозволить виявити спроби змін, але також заблокує будь-які зміни.
  • Визначення параметрів і getters працює, але це вимагає великого коду налаштування, і він не працює добре, коли вам потрібно видалити або створити нові властивості.

Сьогодні ви можете використовувати об’єкт Proxy для контролю (і перехоплення) змін, внесених до об'єкта. Він побудований для того, що намагається зробити ОП. Ось основний приклад:

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найкраще об'єкт поєднується з простими об'єктами або масивами.

Якщо вам потрібно спостерігати за змінами, внесеними до вкладеного об'єкта , вам потрібно скористатись спеціалізованою бібліотекою, такою як Observable Slim (яку я опублікував), яка працює так:

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
@ Cristiano Я думаю, що Елліот намагається сказати, що ви можете використовувати проксі замість фактичного об'єкта, тобто ви можете передавати проксі, як якщо б це був ваш об’єкт, і змушувати інші частини програми взаємодіяти з вашим проксі. Зміни проксі відображатимуться на фактичному об’єкті.
Золтан Матук

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);
}

По-друге, я фактично забув, я підкажу, поки я думаю про це :)

EDIT: О, я пам'ятаю :) Ви можете поставити годинник на значення:

Враховуючи myobj вище, на ньому є "a":

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/Reference/Global_Objects/Object/defineProperty

// 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вимагає 2 аргументів, але частина вашого прикладу показує функцію, яка викликається лише параметром значення.
Hlawuleka MAS

22

Вибачте, що знайдете стару тему, але ось невеликий посібник для тих, хто (як я!) Не бачить, як працює приклад Елі Грей:

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

Сподіваюся, це може комусь допомогти


9
Наразі годинник не підтримується на Chrome або Safari, лише Firefox
Пол МакКлін

5
Для мережі розробників mozilla це не рекомендується. Object.prototype.watch () призначався лише для тестування і не повинен використовуватися у виробничому коді. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Денніс Бартлетт

4
@PaulMcClean ця відповідь була у відповідь на відповідь Елі Грей, яка містила поліфіл. gist.github.com/eligrey/384583
Hobbyist

2
Mozilla поруч із годинником застаріли. Ця відповідь може бути оманливою.
Арно

7

Як відповідь Люка Шафера ( зауважте : це стосується його оригінальної публікації; але вся суть тут залишається дійсною після редагування ), я також запропону пару методів Get / Set для доступу до вашої вартості.

Однак я б запропонував деякі зміни (і тому я публікую ...).

Проблема з цим кодом полягає в тому, що до поля 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!

Інкапсуляція

Отже, щоб гарантувати, що слухачі насправді викликаються, нам доведеться заборонити прямий доступ до поля 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 для інкапсуляції. Це була моя перша думка, але я хотів можливість додати метод create_gets_sets врешті-решт, і оскільки це нерозбірливо, приховувати значення не круто :), ми можемо зробити крок далі і написати деякі речі, щоб приховати значення, але Я думаю, що код, який я опублікував, є досить заплутаним для більшості людей ... можливо, якщо для цього є дзвінок ...
Лука Шафер

6

Якщо ви використовуєте jQuery {UI} (який повинні використовувати всі :-)), ви можете використовувати .change () із прихованим <input /> елементом.


7
Я не зовсім розумію. Як можна приєднати змінну до прихованого <input/>елемента?
Пітер Лі

4
Я думаю, Чак пропонує, що ви можете встановити значення вводу за допомогою jquery, а потім і .change () слухача подій. Якщо ви оновите значення вводу за допомогою .val (), тоді зворотний виклик події .change () запуститься.
jarederaj

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');
Том Уокер

2
Для тих, хто має таку ж проблему, як і я, якщо подія зміни не викликає спробуйте $ ("# thisOne"). Val (myVariableWhichIsNew) .trigger ("змінити"). Надіюсь, це допомагає
Alator

6

AngularJS(Я знаю, що це не так JQuery, але це може допомогти. [Чистий JS хороший лише в теорії]):

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

де "data" - ім'я вашої змінної в області.

Є посилання на doc.


На жаль, це змушує прив’язувати змінну до області застосування
ruX

він $scope.$apply()запускається лише при запуску
iamawebgeek

5

Для тих, хто налаштовується через пару років:

Доступно рішення для більшості веб-переглядачів (і IE6 +), що використовує подію onpropertychange та новіші специфікації defineProperty. Невеликий улов полягає в тому, що вам потрібно зробити свою змінну об'єктом dom.

Повна інформація:

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

Не безпосередньо: вам потрібен парний геттер / сеттер з інтерфейсом "addListener / removeListener" якийсь ... або плагін NPAPI (але це зовсім інша історія).


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(або щось подібне), щоб перевірити, чи ніде ваш код безпосередньо не встановлює значенняglobalVar .

Або ви могли б інкапсулювати його в об єкт та користувальницькі способи отримання та встановлення ... просто думка.


До змінної, яка не є властивістю об'єкта, можна отримати доступ - як це стосується змінних, оголошених varу модулях ES6 - це єдине рішення.
атп

1

Згадайте, хлопці, пам'ятайте, що початкове запитання було для VARIABLES, а не для OBJECTS;)

на додаток до всіх відповідей вище, я створив крихітну губку, яку називають forTheWatch.js , яка використовує той самий спосіб лову та зворотного виклику для зміни звичайних глобальних змінних у JavaScript.

Сумісний зі змінними JQUERY, не потрібно використовувати OBJECTS, і ви можете передати безпосередньо ARRAY з декількох змінних, якщо це необхідно.

Якщо це може бути корисно ...: 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

Це безпосередньо неможливо.

Однак це можна зробити за допомогою CustomEvent: 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']);

Він виявить зміни змінних ім'я користувача та userid.


0

За допомогою геттера та сеттера ви можете визначити клас JavaScript, який робить таке.

Спочатку ми визначаємо наш клас під назвою 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.valзміни не відбувається після змін до 2.

Тепер давайте визначимося з деякими слухачами. У нас є чотири слухачів доступні: beforeSet, beforeChange, afterChange, afterSet. Наступне буде відбуватися послідовно, коли ви використовуєте money.val = newValueдля зміни значення змінної:

  1. money.beforeSet (newValue, oldValue);
  2. money.beforeChange (newValue, oldValue); (Буде пропущено, якщо його значення не буде змінено)
  3. money.val = newValue;
  4. money.afterChange (newValue, oldValue); (Буде пропущено, якщо його значення не буде змінено)
  5. money.afterSet (newValue, oldValue);

Тепер ми визначаємо 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

Це стара тема, але я натрапив на другу найвищу відповідь (користувальницькі слухачі), шукаючи рішення за допомогою Angular. Хоча рішення працює, кутовий має кращий спосіб вирішити це за допомогою @Outputемітерів подій. Виходячи з прикладу у відповіді власного слухача:

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]);}
                    });
            }
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.