Javascript 如何自动注入状态参数 摘要
嗨,我在我的项目中使用angular+ui路由器,我有大量的嵌套状态和不同的视图,它们依次包含大量的不同输入,用户一步一步地递增地填充这些输入 问题 有时用户需要位于上一步的其他信息,浏览器的“后退”按钮帮助用户偷看数据,但一旦用户按下按钮,他已经输入的信息就会由于状态转换而丢失,这显然是一件坏事 策略 为了克服上述问题,我有以下计划:Javascript 如何自动注入状态参数 摘要,javascript,angularjs,angular-ui-router,Javascript,Angularjs,Angular Ui Router,嗨,我在我的项目中使用angular+ui路由器,我有大量的嵌套状态和不同的视图,它们依次包含大量的不同输入,用户一步一步地递增地填充这些输入 问题 有时用户需要位于上一步的其他信息,浏览器的“后退”按钮帮助用户偷看数据,但一旦用户按下按钮,他已经输入的信息就会由于状态转换而丢失,这显然是一件坏事 策略 为了克服上述问题,我有以下计划: 将每个用户的“导航”(猜测这是一个合适的术语)与随机id关联 为了防止范围继承和序列化问题,不要将viewmodel放入$scope中,而是使用普通的javas
$scope
中,而是使用普通的javascript对象来存储绑定到UI的即时值LocalStorage
、IndexedDB
、WebSQL
、会话存储
,您可以说,但由于它们的跨选项卡、跨浏览器、特定于浏览器的特性,很难操作和管理进入存储的所有数据。实现将有缺陷/可能需要服务器端支持
因此,这种情况下最优雅的存储策略是将数据存储在特殊的window.name
变量中,该变量能够在请求之间存储数据。因此,在您关闭选项卡之前,数据是安全的
问题
代表上面写的所有内容,我有一个名为“view”的根视图,它有一个状态参数id
(这是随机GUID/UUID)
所有其他视图都源自此视图,是否有方法使ui sref
指令自动将随机GUID/UUID注入到我的根视图的id
状态参数中,而不是每次写入ui sref
,如:
<a ui-sref="view({id:guid()}).someNestedView({someNestedParam: getParam()})"
AOP和Decorator模式就是答案。全面的描述可以在这里找到: 耶稣罗德里格斯 可以观察到如下所述的类似溶液: 那怎么办?有一个链接到 在本例中,我们不解决随机GUID来自哪个源的问题。让我们在运行时使用它:
var guidFromSomeSource = '70F81249-2487-47B8-9ADF-603F796FF999';
现在,我们可以像这样注入一个装饰器:
angular
.module('MyApp')
.config(function ($provide) {
$provide.decorator('$state', function ($delegate) {
// let's locally use 'state' name
var state = $delegate;
// let's extend this object with new function
// 'baseGo', which in fact, will keep the reference
// to the original 'go' function
state.baseGo = state.go;
// here comes our new 'go' decoration
var go = function (to, params, options) {
params = params || {};
// only in case of missing 'id'
// append our random/constant 'GUID'
if (angular.isUndefined(params.id)) {
params.id = guidFromSomeSource;
}
// return processing to the 'baseGo' - original
this.baseGo(to, params, options);
};
// assign new 'go', right now decorating the old 'go'
state.go = go;
return $delegate;
});
})
代码应该是自解释的,请在操作中检查它如果所有其他状态都是状态“视图”的子级,则可以将对象存储在“视图”控制器的范围内。您可以从嵌套的作用域中对该作用域内的对象进行更改,即使在浏览子对象时,更改也会保持不变。您可以使用“controllerAs”语法来明确哪些数据绑定到“view”范围,哪些数据也绑定到子范围。ui sref还有一个同级视图快捷方式“^.sibling”:)您可以修饰state变量以包含以前的状态吗?或者让一个状态侦听状态更改开始,并将当前状态信息放在状态对象上,以防转换到的下一个状态需要它?除非我遗漏了一些东西,否则您不需要那个复杂的解决方案来检查以前的状态。@horyd我不确定我是否理解您建议的细节,在用户单击浏览器的“后退”按钮后,如何恢复以前的状态?@user814628我是否正确理解,通过“状态变量”您是指存储在URL上的状态参数?我可以侦听状态更改开始事件,但如何知道我们是在层次结构中向前移动还是向后移动,似乎没有关于导致状态更改事件的原因的信息。如果“后退”按钮在状态“视图”的子状态之间导航用户,则不会重新初始化“视图”控制器。控制器中保存的数据将持久化,这是我在Stackoverflow上收到的最有用的答案,谢谢!如果这有帮助的话,那就太好了;)享受绝妙的
UI路由器
;)
var guidFromSomeSource = '70F81249-2487-47B8-9ADF-603F796FF999';
angular
.module('MyApp')
.config(function ($provide) {
$provide.decorator('$state', function ($delegate) {
// let's locally use 'state' name
var state = $delegate;
// let's extend this object with new function
// 'baseGo', which in fact, will keep the reference
// to the original 'go' function
state.baseGo = state.go;
// here comes our new 'go' decoration
var go = function (to, params, options) {
params = params || {};
// only in case of missing 'id'
// append our random/constant 'GUID'
if (angular.isUndefined(params.id)) {
params.id = guidFromSomeSource;
}
// return processing to the 'baseGo' - original
this.baseGo(to, params, options);
};
// assign new 'go', right now decorating the old 'go'
state.go = go;
return $delegate;
});
})