Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何自动注入状态参数 摘要_Javascript_Angularjs_Angular Ui Router - Fatal编程技术网

Javascript 如何自动注入状态参数 摘要

Javascript 如何自动注入状态参数 摘要,javascript,angularjs,angular-ui-router,Javascript,Angularjs,Angular Ui Router,嗨,我在我的项目中使用angular+ui路由器,我有大量的嵌套状态和不同的视图,它们依次包含大量的不同输入,用户一步一步地递增地填充这些输入 问题 有时用户需要位于上一步的其他信息,浏览器的“后退”按钮帮助用户偷看数据,但一旦用户按下按钮,他已经输入的信息就会由于状态转换而丢失,这显然是一件坏事 策略 为了克服上述问题,我有以下计划: 将每个用户的“导航”(猜测这是一个合适的术语)与随机id关联 为了防止范围继承和序列化问题,不要将viewmodel放入$scope中,而是使用普通的javas

嗨,我在我的项目中使用angular+ui路由器,我有大量的嵌套状态和不同的视图,它们依次包含大量的不同输入,用户一步一步地递增地填充这些输入

问题 有时用户需要位于上一步的其他信息,浏览器的“后退”按钮帮助用户偷看数据,但一旦用户按下按钮,他已经输入的信息就会由于状态转换而丢失,这显然是一件坏事

策略 为了克服上述问题,我有以下计划:

  • 将每个用户的“导航”(猜测这是一个合适的术语)与随机id关联
  • 为了防止范围继承和序列化问题,不要将viewmodel放入
    $scope
    中,而是使用普通的javascript对象来存储绑定到UI的即时值
  • 添加观察程序以查找“存储对象”上的更改
  • 一旦发现更改,就序列化对象并将其持久化
  • 解释 为什么我们在URL中需要一个随机参数

    我们不想在URL中存储所有数据,因为可能有相当多的数据不适合URL。因此,为了保证URL不会被破坏,我们只在URL中加入了一个小的随机GUID/UUID,以后可以通过这个随机GUID/UUID获取与当前“导航”相关的数据

    仓库 有许多可用的存储方案:
    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;
        });        
    })