Angular-UI-Router:ui-sref 不使用参数构建 href

Posted

技术标签:

【中文标题】Angular-UI-Router:ui-sref 不使用参数构建 href【英文标题】:Angular-UI-Router: ui-sref not building href with parameters 【发布时间】:2015-04-18 21:21:18 【问题描述】:

我有一个 html 页面,一旦加载到用户的浏览器中,“列表”状态就会被激活,并且“列表”部分由 Angular 拉取并填充了服务器列表。

每个服务器都有一个“详细信息”链接,用于指定该服务器的“详细信息”状态。

<td><a ui-sref="details( serverName: 'server.name' )">Details</a></td>

渲染时,“ui-sref”会根据路由及其可选参数生成预期的“href”url。

<a ui-sref="details( serverName: 'SLCMedia' )" href="#/details/SLCMedia">Details</a>

当点击它时,它会按预期工作,并拉出“详细信息”部分,并在分配给该状态的控制器中拉出指定名称的服务器。

我遇到的问题是,一旦加载了“详细信息”部分,它也有一个“ui-sref”到“编辑”状态。

   <a ui-sref="edit( serverName: 'server.name' )">
        <button class="btn btn-lg btn-labeled btn-primary">
            <span class="btn-label icon fa fa-edit"></span>
            Edit
        </button>
    </a>

但是当这个部分被加载时,'ui-sref' 没有生成正确的 'href' url。

   <a ui-sref="edit( serverName: 'SLCMedia' )" href="#/edit/">
        <button class="btn btn-lg btn-labeled btn-primary">
            <span class="btn-label icon fa fa-edit"></span>
            Edit
        </button>
    </a>

正如您所见,“href”网址是“#/edit/”,而不是预期的“#/edit/SLCMedia”。我想念的东西一定很简单。状态的变化和它有关系吗?

这里是页面定义的所有“状态”。

// Create the Angular App to rule the Server Management Page
var serverApp = angular.module('serverApp', [
    'ui.router',
    'serverControllers',
    'utilitiesService'
]);

serverApp.config(function ($stateProvider, $urlRouterProvider) 
    // For any unmatched url, redirect to /state1
    $urlRouterProvider.otherwise("/list");

    // Now set up the states
    $stateProvider
        .state('list', 
            url: '/list',
            templateUrl: '/views/pages/servers/list.html',
            controller: 'serverListCtrl'
        )
        .state('details', 
            url: '/details/:serverName',
            templateUrl: '/views/pages/servers/details.html',
            controller: 'serverDetailsCtrl'
        )
        .state('create', 
            url: '/create',
            templateUrl: '/views/pages/servers/create.html'
        )
        .state('edit', 
            url: '/edit/:serverName',
            templateUrl: '/views/pages/servers/edit.html',
            controller: 'serverEditCtrl'
        )
);

这是我的控制器

var serverControllers = angular.module('serverControllers', ['utilitiesService']);

serverControllers.controller('serverListCtrl', function ($scope, $http) 
    $http.get('/servers/getList').success(function (data) 
        $scope.serverList = data;
    );
);

serverControllers.controller('serverDetailsCtrl', function ($scope, $stateParams, $http) 
    var serverName = $stateParams.serverName;

    $http.get('/servers/getServerByName/' + serverName).success(function (data) 
        $scope.server = data;
    );
);

serverControllers.controller('serverEditCtrl', function ($scope, $stateParams, $http, $state, showAlertMessage) 
    var serverName = $stateParams.serverName;

    $http.get('/servers/getServerByName/' + serverName).success(function (data) 
        $scope.server = data;
    );

    $scope.server.submitForm = function (item, event) 
        console.log("--> Submitting Server Update");

        //TIMDO: Verify all required fields have been included

        var responsePromise = $http.post("/servers/postEdit", $scope.server, );
        responsePromise.success(function(dataFromServer, status, headers, config) 
            showAlertMessage(
                type: 'success',
                title: 'Success',
                message: 'Server information updated'
            );

            $state.go('clear');
        );
        responsePromise.error(function(data, status, headers, config) 
            showAlertMessage(
                type: 'error',
                title: 'Success',
                message: 'Server information updated'
            );
        );
    
);

【问题讨论】:

【参考方案1】:

嗯,我可能误解了您的问题,但我发现您的代码外观和我的代码外观之间至少有一个明显的区别。

我的 angular-ui-router 链接如下所示:

<a ui-sref="reps-show( id: rep.id )">rep.name</a>

不同之处在于rep.id 周围没有大括号。所以我想知道是否改变这个

<td><a ui-sref="details( serverName: 'server.name' )">Details</a></td>

到这里

<td><a ui-sref="details( serverName: server.name )">Details</a></td>

可能会为你做点什么。

可能不是这样,但这是我首先想到的。

【讨论】:

好吧,移除大括号 成功了!所以这就提出了一个问题,为什么它与列表部分上的大括号一起工作,而不是在细节部分上?我发现完全奇怪的行为。请注意,如果我也删除 ,它仍然适用于列表部分。 我认为这与 ng-repeat 有关,它确保首先:计算表达式,然后:ui-sref 开始了它的魔力。【参考方案2】:

我创建了simplified, but working version here。因为没有什么明显的错误。这个例子至少可以帮助你确保:

您所做的一切都应该是有效的。

以下是状态:

// States
$stateProvider
      .state('list',  
          url: "/list",
          templateUrl: 'tpl.list.html',
          controller: 'serverListCtrl',
      )
      .state('edit', 
        url: '/edit/:serverName',
        templateUrl: 'tpl.html',
        controller: 'serverEditCtrl'
    )

这里是一个列表加载数据的控制器

.controller('serverListCtrl', ['$scope', '$http', function ($scope, $http) 
    $http.get('server.json').success(function (data) 
        $scope.serverList = data;
    );
])

(server.json) - 数据示例

[
  "name":"abc",
  "name":"def",
  "name":"xyz"
]

和同一个模板:

<li ng-repeat="server in serverList">
    <a ui-sref="edit( serverName: 'server.name' )">
        <button class="btn btn-lg btn-labeled btn-primary">
            <span class="btn-label icon fa fa-edit"></span>
            Edit server.name
        </button>
    </a>
</li>

一切都按预期工作。检查它here。

【讨论】:

【参考方案3】:

我想贡献另一个数据点,以防其他人像我一样提出类似的问题。

我在我的应用程序中使用了非大括号版本,但它不起作用。我的具体细节涉及 Google 地图 中的 InfoWindow。我相信存在渲染顺序“问题”,因此 ui-sref 链接所需的数据不存在,当它最终存在时,它永远不会“重新渲染”。

原始(非工作)版本:

%h3
  window_info.data.user.name || "Mystery Person"
%a.fa.fa-info-circle ui:  sref: 'users.show(id: window_info.data.user.id )'  
%pre window_info.data.user.id | json

工作版本:

%h3
  window_info.data.user.name || "Mystery Person"
%a.fa.fa-info-circle ui:  sref: "users.show(id: ' window_info.data.user.id ' )"  
%pre window_info.data.user.id | json

我将%pre 标记与信息一起向自己证明该数据实际上存在(至少最终/最终),但即使链接的原始代码仍然无法正常工作。我根据 OP 的情况调整了我的代码以使用内插花括号版本并且它有效。

结论:您的解决方案可能取决于父组件处理渲染的方式。在这种情况下,Google 地图因其渲染“时髦”(技术术语)而臭名昭著,尤其是在安古地区。

【讨论】:

以上是关于Angular-UI-Router:ui-sref 不使用参数构建 href的主要内容,如果未能解决你的问题,请参考以下文章

动态设置 ui-sref Angularjs 的值

如何实现有条件地执行“ui-sref”?

Angular-ui-router 详解

Angular Directive 未填充 ui-sref

ui-sref的用法

AngularJS UI-Router 中 ui-sref 和 $state.go 的区别