AngularJS 和 ui-router:刷新后错误的路由行为
AngularJS and ui-router: wrong routes behaviour after refresh
我正在使用 AngujarJS 和 ui-router 开发应用程序,但在加载路由时遇到问题。为了便于解释,我将删除部分代码。我的记事本文件如下所示:
app.config(function($stateProvider, $urlRouterProvider,
$locationProvider) {
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl : 'pages/dashboard.html',
controller : 'DashController'
})
.state('dashboard.vendas', {
url: '/vendas',
templateUrl : 'pages/vendas.html',
controller : 'vendasController'
})
;
$urlRouterProvider.otherwise('/');
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
});
我在用户登录后加载此路由 /dashboard。在这条路线上,我加载了一个 http 方法,其中 return 是用户可以访问的公司,通过下面的工厂:
app.factory("factoryEmpresas",
function($http,urlBase,isAuthenticated) {
return {
getEmpresas: function() {
return $http({
url: urlBase.getUrl() + '/empresas',
method: "GET",
headers: {
'X-Token': isAuthenticated.getJWT()
}
}).then(function successCallback(response) {
return response.data;
}, function errorCallback(response) {
return response;
});
}
}
});
访问路由 /vendas(与状态 dashboard.vendas 相关)时,我使用 factoryEmpresas 中的变量进行另一个 http 调用 return如下:
app.factory("factoryVendas",
function($http,urlBase,isAuthenticated) {
return {
getVendas: function(id_empresa) {
return $http({
url: urlBase.getUrl() + '/vendas?id_empresa=' + id_empresa,
method: "GET",
headers: {
'X-Token': isAuthenticated.getJWT()
}
}).then(function successCallback(response) {
return response.data;
}, function errorCallback(response) {
return response;
});
}
}
});
一切正常,直到用户在路线 /vendas 上决定刷新 (F5)。在那一刻,两条路线 /dashboad 和 /vendas 的加载被触发。但是,在 factoryVendas 进行 http 调用时,factoryDashboard 尚未 returned getEmpresas 函数。因此,变量 "empresa_id" 没有填充它应该的值,从而导致未定义的调用代替 "empresa_id".
我问的问题是,如何让 factorySales 等待 factoryDashboard return,以便我可以在正确填写变量的情况下进行调用?
欢迎任何帮助。
谢谢!
听起来 vendas 直接依赖于 empresa。将 empresaId
作为访问 vendas 的路由参数的一部分是否有意义?这样加载页面所需的信息将始终可访问(来自 $stateParams
),即使在重新加载时也是如此
.state('dashboard.vendas', {
url: '/:empresaId/vendas/',
templateUrl : 'pages/vendas.html',
controller : 'vendasController'
});
您可以做的另一件事是通过在父级上创建子级使用的解析来定义加载顺序。然后 uirouter 知道它需要在尝试加载子节点之前等待父节点解析。
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl : 'pages/dashboard.html',
controller : 'DashController',
resolve: {
Empresas: function(factoryEmpresas) {
return factoryEmpresas.getEmpresas();
}
}
})
.state('dashboard.vendas', {
url: '/vendas',
templateUrl : 'pages/vendas.html',
controller : 'vendasController',
resolve: {
Vendas: function(Empresas, factoryVendas) {
var id_empresa = Empresas[0].id; // just kind of guessing here
return factoryVendas.getVendas(id_empresa);
}
}
})
Vendas
和 Empresas
可以注入到它们各自的控制器中。
虽然这行得通,但实际上我不赞成使用这种方法,因为现在您的用户正在等待更多内容出现。研究表明,最好向用户展示渐进的进步,你的应用程序会感觉更快。我尽可能避免解析,并在我的控制器中有初始化逻辑。这样,页面会立即加载并在数据可用时填充。
我正在使用 AngujarJS 和 ui-router 开发应用程序,但在加载路由时遇到问题。为了便于解释,我将删除部分代码。我的记事本文件如下所示:
app.config(function($stateProvider, $urlRouterProvider,
$locationProvider) {
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl : 'pages/dashboard.html',
controller : 'DashController'
})
.state('dashboard.vendas', {
url: '/vendas',
templateUrl : 'pages/vendas.html',
controller : 'vendasController'
})
;
$urlRouterProvider.otherwise('/');
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
});
我在用户登录后加载此路由 /dashboard。在这条路线上,我加载了一个 http 方法,其中 return 是用户可以访问的公司,通过下面的工厂:
app.factory("factoryEmpresas",
function($http,urlBase,isAuthenticated) {
return {
getEmpresas: function() {
return $http({
url: urlBase.getUrl() + '/empresas',
method: "GET",
headers: {
'X-Token': isAuthenticated.getJWT()
}
}).then(function successCallback(response) {
return response.data;
}, function errorCallback(response) {
return response;
});
}
}
});
访问路由 /vendas(与状态 dashboard.vendas 相关)时,我使用 factoryEmpresas 中的变量进行另一个 http 调用 return如下:
app.factory("factoryVendas",
function($http,urlBase,isAuthenticated) {
return {
getVendas: function(id_empresa) {
return $http({
url: urlBase.getUrl() + '/vendas?id_empresa=' + id_empresa,
method: "GET",
headers: {
'X-Token': isAuthenticated.getJWT()
}
}).then(function successCallback(response) {
return response.data;
}, function errorCallback(response) {
return response;
});
}
}
});
一切正常,直到用户在路线 /vendas 上决定刷新 (F5)。在那一刻,两条路线 /dashboad 和 /vendas 的加载被触发。但是,在 factoryVendas 进行 http 调用时,factoryDashboard 尚未 returned getEmpresas 函数。因此,变量 "empresa_id" 没有填充它应该的值,从而导致未定义的调用代替 "empresa_id".
我问的问题是,如何让 factorySales 等待 factoryDashboard return,以便我可以在正确填写变量的情况下进行调用?
欢迎任何帮助。
谢谢!
听起来 vendas 直接依赖于 empresa。将 empresaId
作为访问 vendas 的路由参数的一部分是否有意义?这样加载页面所需的信息将始终可访问(来自 $stateParams
),即使在重新加载时也是如此
.state('dashboard.vendas', {
url: '/:empresaId/vendas/',
templateUrl : 'pages/vendas.html',
controller : 'vendasController'
});
您可以做的另一件事是通过在父级上创建子级使用的解析来定义加载顺序。然后 uirouter 知道它需要在尝试加载子节点之前等待父节点解析。
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl : 'pages/dashboard.html',
controller : 'DashController',
resolve: {
Empresas: function(factoryEmpresas) {
return factoryEmpresas.getEmpresas();
}
}
})
.state('dashboard.vendas', {
url: '/vendas',
templateUrl : 'pages/vendas.html',
controller : 'vendasController',
resolve: {
Vendas: function(Empresas, factoryVendas) {
var id_empresa = Empresas[0].id; // just kind of guessing here
return factoryVendas.getVendas(id_empresa);
}
}
})
Vendas
和 Empresas
可以注入到它们各自的控制器中。
虽然这行得通,但实际上我不赞成使用这种方法,因为现在您的用户正在等待更多内容出现。研究表明,最好向用户展示渐进的进步,你的应用程序会感觉更快。我尽可能避免解析,并在我的控制器中有初始化逻辑。这样,页面会立即加载并在数据可用时填充。