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

时间:2018-12-12 11:19:37

标签: ember.js

我目前使用由其他人编写的{{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(),该逻辑用于根据用户的访问权限将其从路由重定向:

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

我真的很努力地了解如何将transitionTo()段中的车把帮助器中的内容重构为可重用的功能。我什至不确定transitionTo()是否转发与{{link-to}}相同的参数,或者是否必须从其他位置以某种方式获取queryParams。

任何见识将不胜感激。

1 个答案:

答案 0 :(得分:3)

首先,使用诸如_hydrateUnsuppliedQueryParams之类的私有方法是有风险的。这将使升级更加困难。大多数人使用resetController来清除查询条件参数。您还可以通过在过渡中传递空值来明确清除默认值。

但是,请咬一口,因为找出来可能很有趣:)选中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组件可以采用可变数量的动态段,因此需要某种方法来区分传递的动态段,传递的模型和查询参数。