2014-02-20 8 views
1

Я очень стараюсь реализовать history.js a jQuery plugin для IE 8 и 9. Демонстрация в IE10 + и других современных браузерах кажется прекрасной, но я не могу понять проблему ниже для IE < = 9. Демонстрация - это приложение asp.net mvc5, где я хочу предоставить пользователям одну страницу, где я просто загружаю частичные представления и выполняю post action через ajax. Все виды загружаются в div #shell на моем основном представлении. Может быть, я что-то упустил !!Как избежать рендеринга исходного представления сеанса просмотра, когда страница обновляется из другого места в приложении с помощью History.js?

My demo app начинается с http://localhost:1089/, который является первым запросом, который отображает страницу входа. Любое другое pushState() вызывает изменение URL-адреса с добавлением #Home/About?ref=one.

Ниже мой сценарий, который выполняется в layout.cshtml, который загружается только один раз:

(function (window, undefined) { 


     History.Adapter.bind(window, 'statechange', function() { 
      var state = History.getState(); 

      if (state.data.options == undefined) { 
       alert("options is undefined"); 
       var options = { 
        url: state.url, 
        type: "GET", 
        dataType: "html" 
       }; 
       GetPartial(options); 
      } else { 
       GetPartial(state.data.options); 
      } 
     }); 

    })(window); 


$(document).on('click', 'a', function (e) { 
    e.preventDefault(); 

    var options = { 
     url: $(this).prop('href'), 
     type: "GET", 
     dataType: "html" 
    }; 

    History.pushState({ options: options }, $(this).text(), $(this).prop('href')); 
}); 


function GetPartial(options) { 

    if (options) { 

     $.ajax({ 
      url: options.url, 
      type: options.type || 'GET', 
      dataType: options.datatype || 'html', 
      async: true, 
      data: options.dataToPost, 
      beforeSend: function() { 
       $("#loaderMain").show(); 
      }, 
      complete: function() { 
       $("#loaderMain").hide(); 
      }, 
      cache: false, 
     }).success(function(response, status, xhr) { 
      var ct = xhr.getResponseHeader("content-type") || ""; 
      if (ct.indexOf('html') > -1) { 
       // returned result is of type html, so act accordingly 
       if (options.selector == undefined) { 
        InjectContentToShell(response); 
       } else { 
        $(options.selector).empty().append(response); 
       } 
      } else if (ct.indexOf('json') > -1) { 
       // returned result is of type json, so act accordingly 
      } 
     }).fail(function(e) { 
      console.log(e); 
     }); 
    } 
} 


function InjectContentToShell(content) { 
    $('#shell').fadeOut(100, function() { 
     $(this).empty().append(content); 
    }).fadeIn(100); 
} 

Когда я сделать эту первую страницу, добавить одну запись в истории методом PushState как это:

$('#submit').on('click', function (e) { 
     e.preventDefault(); 
     var formInstance = $(this).closest('form'), 
      dataToPost = formInstance.serialize(); 

     var options = { 
      url: formInstance.prop('action'), 
      type: formInstance.prop('method'), 
      dataType: "html", 
      dataToPost: dataToPost 
     }; 

     History.pushState({ options: options }, "Home - All Summary Views", "/Home/Index"); 

    }); 

Нажав вышеприведенное состояние, измените URL-адрес на http://localhost:1089/#Home/Index в браузере html4, что хорошо. Я могу вернуться и вперед. Это хорошо работает.

Теперь, когда я обновляю страницу в браузерах html4, запрос, отправленный на сервер, предназначен для первого URL-адреса i.e. http://localhost:1089/, которые приносят первый вид клиенту. Таким образом, пользователь может видеть первую страницу, например, экран входа в систему. И затем запускается событие statechange, и URL-адрес состояния все еще запоминает последний URL-адрес страницы, где была обновлена ​​страница, и для этого URL-адреса требуется новый запрос. Реакция затем вводится в оболочку.

Итак, проблема в обновлении страницы: пользователь получает два вида мгновенно - начальную страницу, на которой пользователь начал сеанс просмотра, и вскоре вторая страница загружается с сервера и добавляется в оболочку через анимацию, как при событие statechange, History.getState() все еще помнит последний URL-адрес.

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

The above problem is also mentioned as a concept of bookmarking in the this article. Refer to the first figure and the text written above it.

Моя демонстрационное приложение отлично работает в браузерах html5 как на каждом History.pushState() URL браузера меняется на URL я указал. И когда страница обновляется, запрос отправляется на сервер в соответствии с этим URL-адресом, а не с первым URL-адресом в сеансе просмотра.

ответ

0

После попытки многих вещей, я придумал следующее решение не показывать первый взгляд то есть страницы входа для пользователей с html4 браузера:

Я создал вид «Index», который является первым просмотр оказываются. Который не имеет никакого содержания HTML, но имеет следующий скрипт:

<script> 

     $(function() { 
      if (History.getCurrentIndex() == 0) { 

       var options = { 
        url: "/Account/Login", 
        type: "GET", 
        dataType: "html" 
       }; 

       History.pushState({ options: options }, "Login Page", "/Account/Login"); 
      } 
     }); 

    </script> 

Приведенный выше код проверяет, если текущий индекс равен 0 или нет. Если это 0, значит, пользователь только что запустил историю просмотра, и он должен предоставить экран входа в систему. Если это не 0, то это означает, что пользователь находился на другом этапе пользовательского пути внутри приложения, которое ничего не делает. И как только это представление визуализируется, происходит событие statechange, которое уже имеет информацию о URL-адресе страницы, на которой пользователь запрашивает обновление.В соответствии с логикой обработчика событий statechange выше в моем вопросе этот ресурс запрашивается с сервера и вводится в контейнер #shell.

Вышеупомянутое решение работает очень хорошо и дает такой же опыт пользователям, как если бы они находились в браузере html5. Вышеприведенный код работает для меня, но будет рад узнать, есть ли у кого-то другое решение.