Как изменить обработчик событий глобального свойства с помощью KnockoutJS

Я пришел из среды C#, там у нас есть интерфейс INotifyPropertyChanged. При подписке на это событие изменения свойства вы получаете отправителя и имя свойства. В этом примере отправителем является ViewModel. Я хочу иметь что-то подобное с KnockoutJS. Я попытался подписаться и сохранить экземпляр функции в хеш-таблице, которая содержит объект с параметрами ViewModel и PropertyName. Потому что нового значения в наблюдаемом недостаточно для того, для чего я хочу использовать событие.

Как я могу создать код с KO, который работает так же, как INotifyPropertyChanged в C#?

Это какая-то чушь, которую я написал, чтобы показать вам, что я приложил некоторые усилия. Но я терплю неудачу здесь с треском.

var propertyChangedHashTable = new Hashtable();

function PropertyChanged(newValue) {
    console.log(this);
    var changedEventParams = propertyChangedHashTable[this];
    console.log(changedEventParams);
    //gateway.propertyChanged(changedEventParams.viewModel, changedEventParams.propertyName, newValue);
};

function subscribePropertyChanged(viewModel, objectPath) {
    if (typeof objectPath === "undefined" || objectPath == null) objectPath = "";
    if (objectPath.length !== 0) objectPath += '.';
    var observable = ko.observable("").toString();

    for (var propertyName in viewModel) {
        var viewModelName = viewModel.__proto__.constructor.name;
        var localObjectPath = objectPath + viewModelName;
        var property = viewModel[propertyName];
        if (propertyName.indexOf("ViewModel") !== -1) {
            subscribePropertyChanged(property, localObjectPath);
            continue;
        }
        var isObservable = property.toString() === observable.toString();
        if (!isObservable) continue;

        var propertyChangedFunc = PropertyChanged;

        propertyChangedHashTable.put(propertyChangedFunc, 'test');
        property.subscribe(propertyChangedFunc);
    }
}

function MainViewModel() {
    var self = this;
    self.isRecording = ko.observable(false);
    self.dataDirectory = ko.observable("C:\\Temp\\Recordings");
    self.toggleIsRecording = function() {
         self.isRecording(!self.isRecording());
    };
}

var viewModel = new MainViewModel();
subscribePropertyChanged(viewModel);

person Mike de Klerk    schedule 31.08.2017    source источник


Ответы (1)


Из нокаутирующих документов:

Функция подписки принимает три параметра: callback — это функция, которая вызывается всякий раз, когда происходит уведомление, target (необязательный) определяет значение this в функции обратного вызова, а event (необязательный; по умолчанию — «change») — это имя события. чтобы получить уведомление о.

Поэтому, если вы предоставите ViewModel в качестве второго аргумента «цель» для subscribe(), вы сможете получить к нему доступ в обработчике как this. Например:

<p data-bind="text: counter"></p>
<button data-bind="click: buttonClicked">Increment</button>

<script type="text/javascript">
var ViewModel = function() {
    this.counter = ko.observable(0);
    this.buttonClicked = function() {
        this.counter(this.counter() + 1);
    };

    this.counter.subscribe(function(newValue) {
        console.log(newValue);
        console.log(this);
    }, this);
};

ko.applyBindings(new ViewModel());
</script>
person nyrocron    schedule 31.08.2017