Прослушивание изменений переменных в 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 устарел или устарел. Рекомендуемой заменой (для этой же страницы) является объект Proxy.
— Станниус

4
Вопрос только задающий variable, но все ответы здесь относятся property. Интересно, можем ли мы прислушиваться к local variableизменениям?
— Тарик Нугрохотомо

1
есть ли ответ на это? Я имею в виду, чтобы выбрать один
— Braian Mellor

Ответы:


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
Это тонна кода на объект, есть ли способ сделать это более пригодным для повторного использования?
— Ваэль Виктус

Где твой код? Вы начали новый вопрос с этого?
— Акира

Как насчет способа обнаружить, когда новое свойство было добавлено к объекту или было удалено?
— Майкл

Это старый ответ, но я хотел бы добавить, что это хорошо работает для значений массива, а также до тех пор, пока вы устанавливаете значение массива, а не нажимаете на него.
— TabsNotSpaces

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

75

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

  • Object.watch и Object.observe устарели и не должны использоваться.
  • onPropertyChange - это обработчик событий элемента DOM, который работает только в некоторых версиях IE.
  • Object.defineProperty позволяет вам сделать свойство объекта неизменным, что позволит вам обнаруживать предпринятые изменения, но также будет блокировать любые изменения.
  • Определение сеттеров и геттеров работает, но требует большого количества кода установки и не очень хорошо работает, когда вам нужно удалить или создать новые свойства.

Сегодня вы можете использовать объект 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- это можно сделать с помощью a 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

Нет.

Но, если это действительно так важно, у вас есть 2 варианта (первый проверен, второй нет):

Во-первых, используйте сеттеры и геттеры, вот так:

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

Во-вторых, я действительно забыл, я подам, пока я думаю об этом :)

РЕДАКТИРОВАТЬ: О, я помню :) Вы могли бы поставить часы на значение:

Учитывая 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 аргумента, но часть вашего примера показывает, что функция вызывается только с параметром value.
— Хлавулека МАС

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 этот ответ был в ответ на ответ Эли Грея, который содержал Polyfill. 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 ('change'). Надеюсь, это поможет
— Alator

6

AngularJS(Я знаю, что это не так JQuery, но это может помочь. [Чистый JS хорош только в теории]):

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

где «данные» - это имя вашей переменной в области видимости.

Есть ссылка на док.


К сожалению, это заставляет вас связывать переменную с областью действия
— 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

Не напрямую: вам нужна пара getter / setter с интерфейсом «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 .

Или вы можете инкапсулировать его в объектный и пользовательский методы getter и setter ... просто мысль.


Для переменной, которая не является свойством объекта, можно получить доступ - как в случае с переменными, объявленными varв модулях ES6 - это единственное решение.
— атп

1

Пожалуйста, ребята, помните, что первоначальный вопрос был для ПЕРЕМЕННЫХ, а не для ОБЪЕКТОВ;)

в дополнение ко всем ответам выше я создал крошечную библиотеку forTheWatch.js , которая использует тот же способ для отлова и обратного вызова для изменений в обычных глобальных переменных в javascript.

Совместим с переменными JQUERY, нет необходимости использовать OBJECTS, и вы можете при необходимости напрямую передавать массив из нескольких переменных.

Если это может быть полезно ...: 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']);

Он обнаружит изменения в переменных username и userid.


0

С помощью getter и setter вы можете определить класс 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. Несмотря на то, что решение работает, 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.