【问题标题】:How to remove previously provided optional param when changing state with ui-router使用 ui-router 更改状态时如何删除先前提供的可选参数
【发布时间】:2015-09-10 17:18:34
【问题描述】:

我有一个带有可选查询参数的状态。我认为它工作正常,但我发现一旦我指定了可选参数,它就会从那时起保留,因为我导航到与其他参数相同的状态,除非显式删除可选参数。

有没有办法确保在状态更改之间移除可选参数?

这是我想如何更改状态的示例(测试 a 和测试 b),但事实证明我必须使用“测试 d”版本,因为如果之前使用过可选参数,则保留它.

<a ui-sref="test({req: 'a'})">test a</a><br/>
<a ui-sref="test({req: 'b'})">test b</a><br/>
<a ui-sref="test({req: 'c', opt: 'here'})">test c and opt</a><br/>
<a ui-sref="test({req: 'd', opt: undefined})">test d and explicity without opt</a>

这类似于我的状态配置方式:

        $stateProvider.state('test', {
            url: '/{req}?opt',
            params: {
                opt: {value: null, squash: true}
            },
            template: '<h1>req = {{req}}</h1>' +
                    '<h1>opt = {{opt}}</h1>',
            controller: function($scope, $stateParams) {
                $scope.req = $stateParams.req; 
                $scope.opt = $stateParams.opt;
            }
        })

这是jsfiddle。单击前两个链接,它按预期工作,但是一旦单击第三个链接,然后单击前两个链接中的任何一个,您会看到保留了可选参数,即使在前两个链接。

我宁愿不必显式重置可选参数,并让它像可选参数一样实际工作。

有什么想法吗?这是它的设计方式吗?如果是这样,有没有办法让它按照我想要的方式工作?还是我发现了一个错误?

更新

根据以下答案之一,保留可选参数似乎是“按设计”。但是,如果可能的话,我仍在寻找一种有效的解决方法。我从我的应用程序的很多地方转换到状态,其中 99% 没有指定可选参数。我宁愿不必修改所有这些转换并让它们知道可选参数,而是只在我需要的 1% 的时间里指定可选参数。

我尝试创建两个状态“test”和一个子状态“test.opt”,然后正常转换到“test”(即“test a”和“test b”),然后只转换到“test” .opt”当我指定可选参数时。但是,我有一个 rest 调用的解析,它需要知道是否设置了 opt 参数,因此这不起作用,因为解析无法从子级访问“选择”。

更新 #2

我也尝试过复制“test”状态,命名为“testopt”,在这种情况下,唯一的区别是 ?opt 参数。但是,显然 ui-router 无法区分仅通过查询参数不同的两个 url,因此即使 opt 参数是 url 的一部分,它仍会尝试转换为“测试”。

【问题讨论】:

  • 好像你在问这个stackoverflow.com/questions/31542972/… 并且有针对同一个github.com/angular-ui/ui-router/issues/2115 记录的错误
  • 我不认为这是同一个问题。这个问题是关于想要保留可选参数以便“返回”按预期工作。我的问题是它被保留了,即使在新导航到该州时也是如此。该错误的讨论解决方案是缓存状态参数,以便在“返回”时可以访问它们。另外,如您所见,我实际上使用的是 url 上的参数,这有点不同。 SO问题的解决方案说我必须手动删除参数,这就是我试图寻找替代方案的原因。

标签: angularjs angular-ui-router


【解决方案1】:

只需将 inherit=false 的 ui-sref-opts 选项添加到您的链接:

<a ui-sref="test({req: 'a'})" ui-sref-opts="{inherit: false}">test a</a><br/>
<a ui-sref="test({req: 'b'})" ui-sref-opts="{inherit: false}">test b</a><br/>
<a ui-sref="test({req: 'c', opt: 'here'})" ui-sref-opts="{inherit: false}">test c and opt</a><br/>
<a ui-sref="test({req: 'd', opt: undefined})" ui-sref-opts="{inherit: false}">test d and explicity without opt</a>

记录此功能请求和实现的线程:https://github.com/angular-ui/ui-router/issues/376

---- 编辑----

由于上述解决方案似乎并不理想,因为它还需要更新(和维护)每个 ui-sref 锚点以设置所需的行为,另一个解决方案可能是覆盖状态的 go(...) 方法来设置inherit 选项默认为 false。虽然我不确定这是否是推荐的模式,但要做到这一点,请将您的 .config 更改为以下内容:

.config(['$stateProvider', '$provide', function ($stateProvider, $provide) {
    $stateProvider.state('test', {
        url: '/{req}?opt',
        params: {
            opt: {value: null, squash: true}
        },
        template: '<h1>req = {{req}}</h1>' +
            '<h1>opt = {{opt}}</h1>',
        controller: function($scope, $stateParams) {
            $scope.req = $stateParams.req; 
            $scope.opt = $stateParams.opt;
        }
    });

    $provide.decorator('$state', function ($delegate) {
        var state = $delegate;

        state.baseGo = state.go;

        var go = function (to, params, options) {
            options = options || {};

            if (angular.isUndefined(options.inherit)) {
                options.inherit = false;
            }

            this.baseGo(to, params, options);
        };

        state.go = go;
        return $delegate;
    });
}])

【讨论】:

  • 这是一个选项,但似乎与将 opt 设置为 undefined 没有太大区别,例如在“test d”中。情况是我 99% 的链接都是第一种类型,我只有一个地方使用了可选值。如果可能的话,我不想让所有 99% 的其他位置都占一个“可选”参数。
  • 这更接近我想要的,几乎完全正确。但是,有两个问题。首先是 options.inherit 似乎是默认设置的,因此您检查它是否未定义总是失败。但是,即使我在这里强制它为假。通过 ui-sref 建立的链接仍然包含继承的参数。导航可以正常工作,但是如果用户要右键单击并“保存链接”,则参数将在那里。感谢您的帮助和建议。
  • 在我的测试中,options.inherit 默认没有设置。你记得删除 ui-sref-opts 指令吗?上面的两种解决方案是独占的,所以它是一个或另一个。
  • 奇怪。我从未真正放入 ui-sref-opts,甚至搜索了我的整个代码库以查看我是否在任何地方设置了继承,但它仍然在它进来时被定义。但是,在回答第二个问题时,我可以解决通过类似地装饰 $state.href 方法来实现它。
  • 它是“被”定义的,还是“是”被定义的?问题解决了吗?
【解决方案2】:

我有同样的问题,因为参数的默认继承...... 完成上一个答案,JS调用的语法是:

$state.go('new state', {pararemeters... } , {inherit:false});

【讨论】:

  • 这将删除所有 URL 参数,包括可选参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
相关资源
最近更新 更多