Запуск и прослушивание события - PullRequest
1 голос
/ 18 июня 2019

У меня есть класс, который представляет некоторые данные и (короткую) цепочку результатов, полученных из этих данных.Класс имеет три свойства Data1, Data2 и Data3, где Data2 зависит от Data1 (на самом деле это отфильтрованная версия), а Data3 зависит от Data2.

Моя идея состояла в том, чтобы вызвать событие, когда Data1 изменяется, который вычисляет Data2, и затем вызвать другое событие, которое приводит к вычислению Data3.Однако в приведенном ниже тестовом классе Data3 пусто после построения.

Обратите внимание, что я использую uiw.event.EventData из панели инструментов виджетов .

classdef test < handle
    events
        DataChanged 
    end

    properties
        DataChangedListener event.listener
    end

    properties (AbortSet)
        Data1 (:,:) double = []
        Data2 (:,:) double = []
        Data3 (:,:) double = []
    end


    methods
        function self = test()
            self.DataChangedListener = event.listener(self, 'DataChanged', @self.onDataChanged);
            self.Data1 = peaks(64);
        end

        %% setter

        function set.Data1(self, d)
            self.Data1 = d;
            evt = uiw.event.EventData( ...
                'EventType', 'DataChanged', ...
                'Property', 'Data1', ...
                'Model', self );
            self.notify('DataChanged', evt);
        end
        function set.Data2(self, d)
            self.Data2 = d;
            evt = uiw.event.EventData( ...
                'EventType', 'DataChanged', ...
                'Property', 'Data2', ...
                'Model', self );
            self.notify('DataChanged', evt);
        end
        function set.Data3(self, d)
            self.Data3 = d;
            evt = uiw.event.EventData( ...
                'EventType', 'DataChanged', ...
                'Property', 'Data3', ...
                'Model', self );
            self.notify('DataChanged', evt);
        end

        %% Event callback
        function onDataChanged(self, ~, evt)
            switch evt.Property
                case 'Data1'
                    self.Data2 = self.Data1 + 5;
                case 'Data2'
                    self.Data3 = self.Data2 + 10;
            end
        end
    end
end

Есликто-то отлаживает, кто-то видит, что onDataChanged никогда не вызывается с uiw.event.eventData с evt.Property = 'Data2'.

. Кто-нибудь знает, почему и как правильно вызвать событие?

1 Ответ

1 голос
/ 20 июня 2019

Я думаю, что решил головоломку.

Ваш код рекурсивно выполняет обратный вызов слушателя.
По умолчанию рекурсивный слушатель отключен.

См. Концепции событий и прослушивателей :

Рекурсивно - разрешить слушателю запускать то же событие, которое вызвало выполнение обратного вызова. Рекурсивный является ложным по умолчанию. Если обратный вызов запускает событие, для которого он определен как обратный вызов, слушатель не может выполнить рекурсивно. Поэтому установите Recursive в false, если обратный вызов должен инициировать собственное событие. Установка свойства Recursive в true может создать ситуацию, когда бесконечная рекурсия достигает предела рекурсии и вызывает ошибку.

Все, что вам нужно сделать, это установить для свойства Recursive значение true:

После self.DataChangedListener = event.listener(self, 'DataChanged', @self.onDataChanged);

Добавить: self.DataChangedListener.Recursive = true;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...