Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 22.07.2015, 17:02
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Два связанных параметра в config-е класса
В продолжение обсуждения конфигурационных свойств, который был начат в ветке Проблема с созданием класса - Значения свойств передаются другому экземпляру появился вопрос.

Как правильно написать методы update* у двух связанных параметров?

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

Например есть класс Арка. Арку можно определить как через радиус арки, так и через высоту арки. Я пишу такой код:

Ext.define("Arc", {
	
	config: {
		
		height: 0,
		
		radius: 0
		
	},
	
	applyHeight: function(height) {
		this._radius = <расчет радиуса на основании высоты>;
		return height;
	},
	
	applyRadius: function(radius) {
		this._height = <расчет высоты на основании радиуса>;
		return radius;
	}
	
});


Тут мне приходится выкручиваться. Если я вызову this.setRadius() вместо присвоения this._radius = , то все зациклится. И чтобы не запустился apply* связанного параметра, приходится присваивать this._radius =.

Это какой-то недокументированный способ. Я просто подсмотрел, где хранятся конфиги. Оказалось что в переменных с префиксом подчеркивание.

А как правильно это сделать?
__________________
Хусамов Сухроб, Москва, khusamov@yandex.ru
Мой JS-стек: Sencha ExtJS 6, Node.js, TypeScript.
Ответить с цитированием
  #2 (permalink)  
Старый 22.07.2015, 21:43
Аватар для nohuhu
Профессор
Отправить личное сообщение для nohuhu Посмотреть профиль Найти все сообщения от nohuhu
 
Регистрация: 21.05.2015
Сообщений: 321

Стандартных средств для таких случаев нет, поскольку они весьма редки. Я бы использовал простые флаги:

Ext.define('Arc', {
    config: {
        height: 0,
        radius: 0
    },

    applyHeight: function(newHeight) {
        var radius = <считаем радиус>;
        
        // Аксессоры конфигов вызываются в контексте объекта
        if (!this.disableHeightCalc) {
            this.disableRadiusCalc = true;
            this.setRadius(radius);
            this.disableRadiusCalc = false;
        };

        return newHeight;
    },

    applyRadius: function(newRadius) {
        var height = <считаем высоту>;
        
        if (!this.disableRadiusCalc) {
            this.disableHeightCalc = true;
            this.setHeight(height);
            this.disableHeightCalc = false;
        };

        return newRadius;
    },

    constructor: function(cfg) {
        // Мы доверяем входным конфигам, их не надо пересчитывать
        this.disableHeightCalc = this.disableRadiusCalc = true;
        this.initConfig(cfg);
        this.disableHeightCalc = this.disableRadiusCalc = false;
    }
});


Что касается префикса для конфигурационных свойств, то насколько я понимаю, это была такая (тщетная) попытка удержать пользователей от изменения конфигов напрямую, в обход аксессоров. Security by obscurity конечно же не работает, но префиксы оставили как есть для пущей совместимости с Sencha Touch, откуда была притащена система конфигов.

Для большинства классов Ext JS (Classic toolkit в 6) префиксы конфигурационных свойств выключены.
Ответить с цитированием
  #3 (permalink)  
Старый 23.07.2015, 12:32
Аватар для khusamov
Соединяю Node.js и Ext JS
Отправить личное сообщение для khusamov Посмотреть профиль Найти все сообщения от khusamov
 
Регистрация: 25.06.2009
Сообщений: 1,033

Это зачем?

// Мы доверяем входным конфигам, их не надо пересчитывать
this.disableHeightCalc = this.disableRadiusCalc = true;
this.initConfig(cfg);
this.disableHeightCalc = this.disableRadiusCalc = false;


На входе либо радиус либо высота и пересчитать второй параметр обязательно надо, так как getParam не выдаст верное значение того параметра, который не рассчитан.

Кстати, были какие-то неясные проблемы, когда при вызове this.initConfig(cfg) в одном из updateParam() вызывался setOtherParam()... вроде проблема была в том, что параметр не был еще инициализирован что-ли... а на него вызывался setParam()...
__________________
Хусамов Сухроб, Москва, khusamov@yandex.ru
Мой JS-стек: Sencha ExtJS 6, Node.js, TypeScript.
Ответить с цитированием
  #4 (permalink)  
Старый 23.07.2015, 21:43
Аватар для nohuhu
Профессор
Отправить личное сообщение для nohuhu Посмотреть профиль Найти все сообщения от nohuhu
 
Регистрация: 21.05.2015
Сообщений: 321

Сообщение от khusamov Посмотреть сообщение
Это зачем?

На входе либо радиус либо высота и пересчитать второй параметр обязательно надо, так как getParam не выдаст верное значение того параметра, который не рассчитан.
Это для примера, конечно же. Вы знаете свой код, но я-то не знаю. :)

Цитата:
Кстати, были какие-то неясные проблемы, когда при вызове this.initConfig(cfg) в одном из updateParam() вызывался setOtherParam()... вроде проблема была в том, что параметр не был еще инициализирован что-ли... а на него вызывался setParam()...
Насколько я помню, конфигуратор должен такие коллизии обходить. Хотя если возникает круговая ссылка, когда конфиг foo хочет инициализировать конфиг bar, а тот в свою очередь хочет foo, тогда конечно это конечно проблема. Такую проблему можно обойти, отключив механизм взаимных инициализаций перед initConfig, как показано в моём примере; когда конфиг уже готов, можно вызвать setFoo ещё раз.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Использование классов в JavaScript devote Ваши сайты и скрипты 70 01.02.2013 17:17
условие на два параметра virus-07 Javascript под браузер 5 23.01.2012 15:43
Свойства/методы класса TicTac Общие вопросы Javascript 5 03.07.2011 14:53
Sortable, два связанных списка. Как один из них сделать неизменяемым? kvecxjo jQuery 1 30.03.2010 03:15
Два связанных окна micscr Общие вопросы Javascript 1 20.10.2009 19:13