AppGyver Сверхзвуковая навигация между представлениями и создание дубликатов
Я использую AppGyver Steroids и Supersonic для создания приложения, и у меня возникают некоторые проблемы с навигацией между представлениями программно.
Основываясь на документах, вы перемещаетесь между представлениями следующим образом:
var view_obj = new supersonic.ui.View("main#index");
supersonic.ui.layers.push(view_obj);
Однако, когда я проверяю вещи через Chrome DevTools, создается впечатление, что создается второе дублированное представление, т. Е. Если я ухожу от индексной страницы и затем возвращаюсь назад, у меня теперь есть две индексные страницы вместо того, что [я думаю] должно быть один. Это также не закрывает предыдущее представление, на котором я был.
Как я могу предотвратить это и просто перейти к существующему представлению вместо дублирования представлений? Как закрыть вид после того, как отошел от него?
Благодарю.
3 ответа
Проблема, с которой вы сталкиваетесь, заключается в том, что вы создаете new supersonic.ui.View("main#index")
каждый раз, когда вы перемещаетесь. Кроме того, я думаю, что вы хотите вернуться к тому же представлению, когда вы возвращаетесь к представлению во второй раз, т.е. вы хотите, чтобы представление оставалось в памяти, даже если оно было удалено из стека навигации с помощью pop()
(вместо того, чтобы выдвигать новый экземпляр этого представления). Для этого вам нужно предварительно загрузить или " start()
"вид, как описано в документации здесь.
Я реализовал свою собственную вспомогательную функцию, чтобы сделать это проще; вот мой код:
start = function(dest, isModal) {
var viewId=dest,
view=new supersonic.ui.View({
location: dest,
id: viewId
});
view.isStarted().then(function(started) {
if (started) {
if (isModal) {supersonic.ui.modal.show(view);}
else {supersonic.ui.layers.push(view);}
} else {
// Start Spinner
supersonic.ui.views.start(view).then(function() {
if (isModal) {supersonic.ui.modal.show(view);}
else {supersonic.ui.layers.push(view);}
// Stop Spinner
}, function(error) {
// Stop Spinner
A.error(error);
});
}
});
};
Используйте это как start('module#view');
, В качестве бонуса вы можете передать true
в качестве второго аргумента, и вместо этого он выдвигается как модальный.
Он проверяет, если вы уже начали просмотр - если это так, он просто возвращает это представление обратно в стек. Если нет, то это start()
s (то есть предварительно загружает) это, затем толкает это. Это гарантирует, что представление остается в памяти (с любым пользовательским вводом, который был изменен), даже когда вы pop()
это из стека.
Вы должны представить, что стек слоев на самом деле является стеком в смысле информатики. Вы можете только добавлять и удалять представления в верхней части стека. Следствием этого является то, что сложные переходы, такие как A > B > C > D > B, трудны / хакерские (в этом случае вам придется pop()
D и C по очереди, чтобы вернуться к B).
Представления закроются, если вы pop()
их, пока вы этого не сделали start()
их. Если вы сделали, и вы pop()
их, они остаются в памяти. Чтобы убить эту точку зрения, вы должны позвонить stop()
на нем, как описано в документах, которые я связал выше.
Спасибо LeedsEbooks за помощь в решении этой проблемы. Я смог найти решение. Вот код:
var start = function(route_str, isModal) {
var regex = /(.*?)#(.*)/g;
var match_obj = regex.exec(route_str);
var view_id_str = match_obj[2],
view_location_str = route_str,
view = new supersonic.ui.View({
location: view_location_str,
id: view_id_str
});
view.isStarted().then(function(started) {
if (started)
{
if (isModal)
{
supersonic.ui.modal.show(view);
}
else {
supersonic.ui.layers.push(view);
}
}
else
{
// Start Spinner
supersonic.ui.views.start(view).then(function() {
if (isModal)
{
supersonic.ui.modal.show(view);
}
else
{
supersonic.ui.layers.push(view);
}
// Stop Spinner
}, function(error) {
// Stop Spinner
A.error(error);
});
}
});
};
Вы должны убедиться, что ваш маршрут имеет формат module#view
как определено в документации.
ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ
Кажется, существует некоторая проблема со сверхзвуковым методом пользовательского интерфейса для запуска представлений. Если вы запустите следующий код:
supersonic.ui.views.start("myapp#first-view");
supersonic.ui.views.find("first-view").then( function(startedView) {
console.log(startedView);
});
Вы заметите, что ваш взгляд id
а также location
идентичны Это кажется неправильным, так как id
должно быть first-view
а также location
должно быть myapp#first-view
,
Поэтому я решил не использовать методы AppGyver и вместо этого создать собственный метод предварительной загрузки, который я запускаю с контроллера, подключенного к моему домашнему представлению (это гарантирует, что все представления, которые я хочу предварительно загрузить, будут обрабатываться при загрузке приложения). Вот функция для этого:
var preload = function(route_str)
{
var regex = /(.*?)#(.*)/g;
var match_obj = regex.exec(route_str);
var view = new supersonic.ui.View({
location: route_str,
id: match_obj[2]
});
view.start();
};
Делая это, я уверен, что представление будет загружено с правильным location
а также id
и что, когда я использую мой start()
работать позже, у меня не будет никаких проблем.
Вы хотите убедиться, что ваш structure.coffee
файл не имеет preload
инструкции, чтобы не создавать повторяющиеся представления, с которыми у вас возникнут проблемы позже.
Наконец, у меня есть представление, что это 2 уровня в форме, которая отправляет данные с помощью операции AJAX. Я хотел, чтобы представление вернулось к предыдущему виду, когда операция AJAX была завершена. Использование моей предыдущей функции привело к push()
быть отклоненным Было бы неплохо, если бы AppGyver Supersonic мог разумно обнаружить, что при переходе к предыдущему виду по умолчанию layers.pop
операция, но вы не всегда получаете то, что вы хотите. Во всяком случае, мне удалось решить это с помощью supersonic.ui.layers.pop()
, который просто делает то, что сделал бы кнопка Назад.
Все работает, как задумано сейчас.
Пытаться
var view_obj = new supersonic.ui.View("main#index");
supersonic.ui.layers.replace(view_obj);
И взгляните на supersonic.ui.layers.pop ();