使用window.location禁用UI-Router交互

Eri*_* H. 6 javascript jquery window.location angularjs angular-ui-router

这是一个很长的镜头,但UI路由器是如此受欢迎,以为可能有人在这里可以洞察这个问题.

我正在将项目迁移到Angular JS.该项目由一个包含多个不同面板的页面组成 - 每个面板都是从服务器下载的,带有AJAX的HTML,用Javascript注入到页面中,并与jQuery History管理的自己的href相关联.

jQuery历史跟踪浏览器状态并在每个面板注入Javascript后相应地更新window.href.例如:

Panel 1:
  window.location.href // http://myapp.com/panel1
  History.getLocationHref() // http://myapp.com/panel1
  History.getPageUrl() // http://myapp.com/panel1
Panel 2:
  window.location.href // http://myapp.com/panel2
  History.getLocationHref() // http://myapp.com/panel2
  History.getPageUrl() // http://myapp.com/panel2
Panel 3:
  window.location.href // http://myapp.com/panel3
  History.getLocationHref() // http://myapp.com/panel3
  History.getPageUrl() // http://myapp.com/panel3
Run Code Online (Sandbox Code Playgroud)

等等

因为每个面板都是注入的,而不是在注入DOM后用Angular编译它们,所以我为每个面板引导了单独的AngularJs应用程序.到目前为止,这已经很好了.

现在我在Panel 2中使用AngularJs UI-router - 所以我可以在替代模板中呈现数据.问题是,UI-Router必须以某种方式混淆浏览器历史记录和/或窗口href.因为一旦该应用程序被实例化,让我说我从Panel 1开始,然后单击Panel 2,然后单击Panel 3,我遇到了这个问题:

Panel 1:
  window.location.href // http://myapp.com/panel1
  History.getLocationHref() // http://myapp.com/panel1
  History.getPageUrl() // http://myapp.com/panel1
Panel 2:
  window.location.href // http://myapp.com/panel2
  History.getLocationHref() // http://myapp.com/panel2
  History.getPageUrl() // http://myapp.com/panel2
Panel 3:
  window.location.href // http://myapp.com/panel2
  History.getLocationHref() // http://myapp.com/panel2
  History.getPageUrl() // http://myapp.com/panel3
Run Code Online (Sandbox Code Playgroud)

基本上,一旦用应用程序实例化UI-Router,jQuery History就不再有效,并且位置href仍然存在于ui-router应用程序的URL中.

我可以做些什么来禁用ui-router与窗口位置href的交互?或者是模块如何工作的组成部分?

这是我的panel2.states.js文件,如果它有帮助:

angular.module("panel2")
.config(["$stateProvider", function($stateProvider) {
  $stateProvider
    .state('table', {
      views: {
        index: {
 //             controller: "TableController as at",
            templateUrl: "table.html"
        }
      }
    })
    .state('tiles', {
      views: {
        index: {
//              controller: "TilesController as tc",
            templateUrl: "tiles.html"
        }
      }
    });
}]);
Run Code Online (Sandbox Code Playgroud)

更新(4/27/2015)

我解决了我的特殊问题,只是摆脱了jQuery History以及它增加的功能,超出了我们的需要.相反,我只是直接与window.history:

 window.history.pushState({panel: "panel3"}, 
    document.title + " | " + 'panel3', 
    window.location.href + "/panel3");
Run Code Online (Sandbox Code Playgroud)

我仍然很好奇是什么导致了这种交互,如果角度或角度ui路由器直接与window.location交互?

Tid*_*ddo 1

Angular 公开了$location与对象交互的服务window.location,我很确定ui-router使用该服务而不是window.location直接使用对象。您可以从函数中装饰服务以拦截对该服务的所有调用并提供您自己的不使用.$locationconfig$locationwindow.location

例如(高度简化):

$provide.decorate('$location', function($delegate) {
    var currentUrl = '';
    //we base the proxy on the original
    var locationProxy = Object.create($delegate);
    //and overwrite what we need
    locationProxy.url = function(newUrl) {
        if (newUrl) {
            $rootScope.$broadcast('$locationChangeStart' /* other event args here*/);
            currentUrl = newUrl;
            $rootScope.$broadcast('$locationChangeSuccess' /* other args here */);
        } else {
            return currentUrl;
        }
    };

});
Run Code Online (Sandbox Code Playgroud)

它确实要求您以与原始服务兼容的方式实现所有功能$location,因此这可能会是相当大量的工作。