如何将 {{link-to}} helper 重构为可以在 transitionTo 中使用的函数?

How to refactor {{link-to}} helper into a function that can be used in transitionTo?

我目前使用由其他人编写的 {{link-to}} 助手来显式声明查询参数以传递到下一个路由并删除其他未声明的参数。它看起来像这样:

//link-to example

{{#link-to 'route' (explicit-query-params fromDate=thisDate toDate=thisDate)} Link Text {{/link-to}}

//the helper

import {helper} from '@ember/component/helper';
import Object from '@ember/object';
import {assign} from '@ember/polyfills';

export function explicitQueryParams(params, hash) {
  let values = assign({}, hash);
  values._explicitQueryParams = true;

  return Object.create({
    isQueryParams: true,
    values,
  });
}

export default helper(explicitQueryParams);

// supporting method in router.js

const Router = EmberRouter.extend({
  _hydrateUnsuppliedQueryParams(state, queryParams) {
      if (queryParams._explicitQueryParams) {
        delete queryParams._explicitQueryParams;

        return queryParams;
      }
      return this._super(state, queryParams);
    },

});

我最近有一个用例,我需要将相同的逻辑应用于 transitionTo(),该 transitionTo() 用于根据用户的访问从路由重定向用户:

 beforeModel() {
    if (auth) {
      this.transitionTo('route')
    } else {
      this.transitionTo('access-denied-route')
    }
},

我真的很想知道如何将车把助手中的内容重构为 transitionTo() 段中的可重用函数。我什至不确定 transitionTo() 是否转发与 {{link-to}} 相同的参数,或者我是否必须以某种方式从不同的位置获取 queryParams。

如有任何见解,我们将不胜感激。

首先,使用 _hydrateUnsuppliedQueryParams 这样的私有方法是有风险的。这将使升级变得更加困难。大多数人使用 resetController 来清除 stick 查询参数。您还可以通过在转换中传递空值来明确清除默认值。

但是,不好意思,因为弄清楚这个很有趣 :) 检查这个 ember-twiddle 是否符合您的要求。

如果您从头开始处理 transitionTo 案例,我们可以在 router.js 实施中看到:

transitionTo(...args) {
    let queryParams;
    let arg = args[0];
    if (resemblesURL(arg)) {
      return this._doURLTransition('transitionTo', arg);
    }

    let possibleQueryParams = args[args.length - 1];
    if (possibleQueryParams && possibleQueryParams.hasOwnProperty('queryParams')) {
      queryParams = args.pop().queryParams;
    } else {
      queryParams = {};
    }

    let targetRouteName = args.shift();
    return this._doTransition(targetRouteName, args, queryParams);
  }

因此,如果最后一个参数是一个带有查询参数 obj 的对象,它将直接进入 _doTransition,最终调用:

_prepareQueryParams(targetRouteName, models, queryParams, _fromRouterService) {
    let state = calculatePostTransitionState(this, targetRouteName, models);
    this._hydrateUnsuppliedQueryParams(state, queryParams, _fromRouterService);
    this._serializeQueryParams(state.handlerInfos, queryParams);

    if (!_fromRouterService) {
      this._pruneDefaultQueryParamValues(state.handlerInfos, queryParams);
    }
}

具有_hydrateUnsuppliedQueryParams的功能。因此,要使这一切正常工作,您不能直接从您创建的 helper 共享函数。相反,只需将 _explicitQueryParams: true 添加到您的查询参数中。任务完成 :) link-to 版本不同。查询参数使用

let queryParams = get(this, 'queryParams.values');

因为 link-to 组件可以采用可变数量的动态段,因此需要某种方式来区分传递的动态段、传递的模型和查询参数。