Дюрандаль: Как выйти из текущего представления с помощью функции активации() этого представления?

У меня есть следующее:

function activate(routeData) {
    // make dataservice call, evaluate results here.  If condition is met, reroute:
    if (true){
       router.navigateTo("#/someRoute");
     }
    alert ("should not be shown");
}

Однако оповещение срабатывает, и затем представление меняется.

Как мне полностью уйти от текущего элемента и предотвратить попадание любого другого кода в эту виртуальную машину?

Обновление:

Я пытался использовать guardroute, но мне нужно активировать viewModel, чтобы вызвать службу данных, которая возвращает данные, определяющие, следует ли мне перенаправить маршрут. Использование guardroute полностью предотвращает вызов службы данных (поскольку ничего в функции активации не будет выполнено).

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


person SB2055    schedule 27.06.2013    source источник


Ответы (5)


Вот ответ @EisenbergEffect на довольно похожее обсуждение в группах Google.

Реализуйте canActivate в своей модели представления. Возвратите обещание false, затем цепочку с перенаправлением.

Вы можете попробовать пример @JosepfGabriel (обсуждение) в Durandal. 1.2. Проверьте правильный синтаксис router для вашей версии Durandal, возможно, вам придется заменить его чем-то вроде router.navigateTo("#/YourHash", 'replace').

canActivate: function () {
    return system.defer(function (dfd) {
        //if step 2 has a problem
        dfd.resolve(false);
    })
    .promise()
    .then(function () { router.navigate("wizard/step1", { trigger: true, replace: true }); });
}

Однако это НЕ работает в Durandal 2.0, и есть запрос функции https://github.com/BlueSpire/Durandal/issues/203 для этого.

person RainerAtSpirit    schedule 28.06.2013

В Durandal 2.0 у меня работало следующее:

    canActivate: function() {
        if(condition)
            return {redirect: 'otherRoute'};
        return true;
    }

    activate: // Do your stuff

Это упоминается в документации: http://durandaljs.com/documentation/Using-The-Router.html

person Autosonic    schedule 20.09.2013
comment
Из документации: Как обычно, вы можете вернуть true/false (или обещание) из обратного вызова canActivate. Но с маршрутизатором вы также можете вернуть инструкцию маршрута, которая указывает URL-адрес перенаправления, если вы хотите запретить активацию. Например, вы можете вернуть {redirect:'some/other/route'} из canActivate. - person Svakinn; 08.08.2014

Вы не можете вызвать перенаправление в активный метод.

Вы можете переопределить метод guardRoute из маршрутизатора, чтобы реализовать перенаправления.

Вы можете сделать что-то вроде этого:

router.guardRoute= function(routeInfo, params, instance){
  if(someConditios){
    return '#/someRoute'
  }
}

Вы можете вернуть обещание, истину, ложь, маршрут для перенаправления... Вы можете найти больше информации об этом по следующей ссылке: http://durandaljs.com/documentation/Router/

person jvrdelafuente    schedule 27.06.2013
comment
Что, если я получу результаты некоторых условий только из метода активации виртуальной машины, из которой я пытаюсь выйти? Я вызываю конечную точку API, чтобы получить данные для определенного представления, но если возвращаемые данные соответствуют условию, мне нужно плавно перенаправить их к другому представлению. - person SB2055; 27.06.2013
comment
Вы можете проверить это в guardRoute, вы можете узнать, на какой странице вы находитесь, используя routeInfo. Я знаю, что это не идеально, но вы не можете перенаправить в активацию. По следующей ссылке есть дополнительная информация: groups.google.com/forum/#!searchin/durandaljs/ - person jvrdelafuente; 27.06.2013
comment
подождите ... Я только что попробовал это, и у меня все еще есть проблема. В функции активации моей виртуальной машины я вызываю службу данных - моя оболочка (где я устанавливаю guardroute) не имеет к этому доступа. Вы говорите, что мне нужно получить данные от службы данных и каким-то образом отправить их на маршрутизатор? Это сбивает с толку, потому что для того, чтобы получить данные, которые определят, должен ли маршрут измениться, мне нужно активировать другой маршрут, поэтому я не могу его блокировать/охранять. Имеет ли это смысл? - person SB2055; 27.06.2013
comment
Может быть, есть другой способ, но я не знаю. :( Если вы объясните больше о том, что вы пытаетесь проверить, я могу попытаться вам помочь. - person jvrdelafuente; 27.06.2013
comment
Спасибо - я только что обновил свой первоначальный пост - надеюсь, это немного яснее объясняет, с чем я столкнулся. - person SB2055; 27.06.2013

Ответ Райнера был довольно хорошим, и я добавляю это небольшое исправление.

Внутри блока then() просто вызовите навигацию следующим образом.

setTimeout(function() { router.navigateTo('#/YOUR DESTINATION'); }, 200);

это должно решить вашу проблему. setTimeout делает свое дело. Без него новая просматриваемая страница перехватывает старую NavigationCancel из предыдущей.

person zewa666    schedule 09.07.2013

Добавление возврата в блок if (true) должно исправить это.

function activate(routeData) {
    if (true){
       router.navigateTo("#/someRoute");
       return;
     }
    alert ("should not be shown");
}
person Jacques Snyman    schedule 27.06.2013
comment
Это работает для «активировать», но представление, от которого я ухожу, все еще загружается, поэтому viewAttached попадает. Я пытаюсь полностью выйти из представления - person SB2055; 27.06.2013
comment
я немного расстроен, что увидел это только сейчас; может через 7 лет ты увидишь свою ошибку? - person Pogrindis; 04.04.2020
comment
Не уверен, что я следую? Что ты имеешь в виду? - person Jacques Snyman; 06.04.2020