从属性类型指令(不是组件)访问 ui-路由器状态参数

Accessing ui-router state params from an attribute-type directive (NOT a component)

我们正在从非常旧的 UI 路由器版本升级到 v1.0.5,我在尝试替换我们已弃用的 $stateParams 使用时遇到了问题。举一个简化的例子,我们有一个 unique-name 属性类型指令,我们在表单字段上使用它来进行验证检查,以确保字段中的文本是唯一的名称。我们的想法是,我们要么添加新的 doohickey,要么更改现有 doohickey 的名称,我们希望确保没有其他 doohickey 具有相同的名称。

在我们的旧代码中,我们可以像这样从 $stateParams 中获取 doohickeyId 值:

function uniqueName(doohickeySearchService, $stateParams, $q) {
        return {
            restrict: 'A',
            require: 'ngModel',
            link: function (scope, elm, attrs, ctrl) {
                ctrl.$asyncValidators.uniqueName = function (modelValue) {
                    // use doohickeySearchService to look up foundDoohickey by name
                    // then...
                    return foundDoohickey.id !== $stateParams.doohickeyId;
                };
            }
        };
    }

可能过于简单了,但问题的核心在于:我们如何在不使用已弃用的 $stateParams 的情况下访问 doohickeyId 值?有一个从 url 获取它的父状态,这类似于状态定义中指定的 /doohickey/{doohickeyId:int}/edit

我可以使用 $state 获取 $current 状态,以及来自 path 属性 的状态数组,我什至可以看到 [=13] =] 参数在路径中的状态之一。不幸的是,如果我采用参数的 value(),它返回未定义,即使 $stateParams 具有正确的 doohickeyId 值。我也试过添加 doohickeyId 作为对父状态的解析,但不幸的是,这并没有给我任何我需要的关于属性类型指令的数据。

阅读文档和谷歌搜索正在查找从子 states 或组件访问父数据的引用,但我正在尝试从属性类型指令获取访问权限,而不是 state/component。有没有办法在不对我们的代码库进行大修的情况下做到这一点?

将数据作为属性类型指令的值传递。然后通过 link 函数中的 attrs 参数检索它。然后根据范围对其进行评估。

<input unique-name="{doohickeyId: doohickeyIdFromStateParams}" />

link: function (scope, elm, attrs) {
    var data = scope.$eval(attrs.uniqueName));

    console.log('My doohickey ID is: ', data.doohickeyId);

}

我在离线状态下找到了答案,但我想 post 在这里以供将来参考。我们决定采用的方法是建立我们自己的自定义全局状态服务来保存状态参数。所以在 app/app.js 中,我们在 app.run() 中得到了类似的东西:

$transitions.onFinish({}, function ($transition$) {
    customStateService.setCurrentStateParams($transition$);
});

然后我们可以在任何需要的地方注入我们的 customStateService,并调用一个 getCurrentStateParams() 函数来检索在最近成功的状态转换中可用的任何参数,类似于我们之前使用的方式$stateParams.

您是否尝试过 UI-路由器文档中的这个解决方案?

Instead of using the global $stateParams service object,

inject $uiRouterGlobals and use UIRouterGlobals.params

MyService.$inject = ['$uiRouterGlobals'];
function MyService($uiRouterGlobals) {
  return {
    paramValues: function () {
      return $uiRouterGlobals.params;
    }
  }
}

Instead of using the per-transition $stateParams object,

inject the current Transition (as $transition$) and use Transition.params

MyController.$inject = ['$transition$'];
function MyController($transition$) {
  var username = $transition$.params().username;
  // .. do something with username
}

https://ui-router.github.io/ng1/docs/latest/modules/injectables.html#_stateparams