Отображение компонента только после загрузки данных для его модели просмотра

У меня есть метод на моем контроллере, который срабатывает при нажатии на сетку в моем приложении.

При щелчке по строке сетки я создаю новый экземпляр виджета окна сведений, беру его модель просмотра и создаю ссылку. После создания этой ссылки я показываю окно:

...
itemClicked: function (item, record, index, event, eOpts){

    var detailsWindow = Ext.widget('sessiondetails'),
        viewmodel = detailsWindow.getViewModel();


    viewmodel.linkTo('sessiondetails', {
        reference: 'Registration.model.SessionDetails',
        id: record.id
    });
    detailsWindow.show();
}
...

Класс модели, на который имеется ссылка в вызове метода linkTo, имеет конфигурацию прокси-сервера rest, поэтому, когда linkTo запускается, для данных выполняется запрос GET:

Ext.define('Registration.model.SessionDetails', {
    extend: 'Ext.data.Model',
    fields: [
        ...
    ],
    proxy:{
        type: 'rest',
        url: 'sessions',
        reader: {
            type: 'json',
            rootProperty: 'record'
        }
    }
});

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

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

Я бы предпочел иметь возможность отображать окно замаскированным, а затем демаскировать его после загрузки данных. Я знаю, что могу использовать метод .mask() после отображения окна:

...
detailsWindow.show();
detailsWindow.mask('Loading...');

Но я не могу понять, как удалить маску после того, как ViewModel завершил загрузку записи.

Как бы я это сделал? Я неправильно подхожу к этому?

Обновление: исправление

Основываясь на втором варианте ответа Роберта Уоткинса, я реорганизовал свой код, чтобы:

  • Показать и замаскировать окно сразу
  • Загрузить запись прямо из модели
  • In the success callback for the load method
    • Set the returned data into the ViewModel
    • Разоблачить окно

Вот обновленный метод:

itemClicked: function (item, record, index, event, eOpts){

    // create the window
    var detailsWindow = Ext.widget('sessiondetails');

    // Get an instance of the model class
    var model = Registration.model.SessionDetails;

    // manually load the record
    // Note that this would be the same as firing
    // Registraton.model.SessionDetails.load(...), 
    // I just think it reads better this way
    model.load(record.id, {

        // Make sure you include the `scope: this` config, 
        // otherwise you won't have access to the 
        // previously defined `detailswindow` variable
        scope: this,
        success: function (session){
            var viewmodel = detailsWindow.getViewModel();
            viewmodel.setData(session.getData());

            // Since this callback fires after the data is returned,
            // placing the unmask here makes sure the data is loaded first.
            detailsWindow.unmask();

        }
    });

    // Show and mask the window
    detailsWindow.show();
    detailsWindow.mask('Loading...');
}

person Chris Schmitz    schedule 10.09.2015    source источник
comment
Можете ли вы использовать маршрутизацию? Вы можете настроить до в маршруте и возобновить действие при успешном вызове функции загрузки в модели. В «нормальной» функции маршрута вы показываете окно, используя идентификатор (который является параметром хэша маршрута).   -  person Tarabass    schedule 10.09.2015
comment
Хм, я следую логике, которую вы излагаете, но я все еще немного неопытен, когда дело доходит до выяснения того, как это будет применяться в моем проекте. Я немного изучу и посмотрю, смогу ли я это понять.   -  person Chris Schmitz    schedule 11.09.2015
comment
docs.sencha.com/extjs/6.0/application_architecture/router.html   -  person Tarabass    schedule 11.09.2015
comment
Ой! Моя беда, я точно знаю роутер. Почему-то я подумал, что это что-то другое. Спасибо за ссылку. Я подумаю, можно ли лучше реорганизовать то, что у меня есть сейчас, с помощью кода, используемого для маршрутизации в конкретный сеанс (что является хорошей идеей).   -  person Chris Schmitz    schedule 11.09.2015
comment
Это все зависит от вас. Вы должны поддерживать код. Вот еще одна статья о маршрутизации и пользовательских сеансах: sencha.guru/ 02.07.2015 / обработка-пользователь-сеанс-с-маршрутами   -  person Tarabass    schedule 11.09.2015


Ответы (1)


Попробуйте создать собственную привязку:

this.maskBinding = this.getViewModel().bind({ bindTo: 'sessiondetails', single: true, }, function() { detailsWindow.unmask(); })

Привязка вызовет предоставленную функцию при изменении привязанного значения (значение sessiondetails). Это должно вызываться при загрузке записи.

(NB: я не пробовал этот конкретный подход, но раньше я использовал привязки для обнаружения изменений значений).

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

person Robert Watkins    schedule 10.09.2015
comment
Я пробовал привязку в первой части вашего ответа. Он работал до применения маски, но обратный вызов должен происходить после создания значения sessiondetails, но до заполнения данными элементов окна. Вы видите, что маска мигает на долю секунды, а затем она демаскируется перед загрузкой данных. Сейчас я собираюсь попробовать второй вариант, чтобы посмотреть, как все пойдет. - person Chris Schmitz; 11.09.2015
comment
Второй вариант сработал. Я дополню свой ответ кодом, который использовал для иллюстрации. Спасибо!! - person Chris Schmitz; 11.09.2015