簡體   English   中英

角狀態解析未注入控制器

[英]Angular state resolve not injecting into controller

我正在嘗試獲取ui路由器的portalsForUserCtrl以將其值傳遞給控制器portalsForUserCtrl

這是路由器:

(function () {
'use strict';

var myApp = angular.module("myApp", ["common.services", "ui.router", 'ngMessages']);

    myApp.config(["$stateProvider", "$urlRouterProvider",
    function ($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise("/");

        $stateProvider
            .state("portalsForUser", {
                url: "/userPortal/portalsForUser/:id",
                templateUrl: "app/userPortal/portalsForUser.html",
                controller: "portalsForUserCtrl as vm",
                resolve: {
                    userPortalService: "userPortalService",
                    portalsForUser: function (userPortalService, $stateParams) {
                        var userId = $stateParams.id;
                        console.log(userId);  //shows userId correctly
                        return userPortalService.getPortalsForUserPromise(userId)
                            .then(function (response) {
                                var userPortals = response.data;
                                console.log("userPortals", userPortals); //shows portals
                                return userPortals;
                            });
                    }
                }
            })
    }]
);

這是整個控制器:

(function () {
"use strict";

angular.module("myApp")
  .controller("portalsForUserCtrl", portalsForUserCtrl);

  portalsForUserCtrl.$inject = ['portalsForUser', 'userPortalService'];

  function portalsForUserCtrl(portalsForUser, userPortalService) {
    console.log("in portalsForUserCtrl");
    var vm = this;
    vm.portalsForUser = portalsForUser;
    console.log(portalsForUser);
  }

}());

在mainCtrl(它是index.html的控制器)中,我調用:

$state.go("portalsForUser", ({ "id": userId }));

以下是視圖app / userPortal / portalsForUser.html的代碼:

<div class="container">
    <table class="table table-condensed table-striped table-bordered">
    <tbody>
        <tr>
            <th class="col-md-2">&nbsp;</th>
            <th class="col-md-4">
                Portal Name
            </th>
        </tr>

        <tr ng-repeat="userPortal in vm.portalsForUser">
            <td>
                {{userPortal.portal.portalName}}
            </td>
            <td class="">
                <a class="btn btn-primary" ui-sref="goSomewhere({id: userPortal.portal.id})">
                    Go
                </a>
            </td>
        </tr>
    </tbody>
</table>

這是userPortalService的代碼:

(function () {
"use strict";

angular.module("myApp")
    .service('userPortalService', userPortalService);

userPortalService.$inject = ['userPortalResource', '$http', 'appSettings']

  function userPortalService(userPortalResource, $http, appSettings) {

    var getPortalsForUserPromise = function (id) {
        return $http.get(appSettings.serverPath + '/api/UserPortal/GetPortalsForUser/' + id);
    };

    return {
        getPortalsForUserPromise: getPortalsForUserPromise
    };
  }

}());

URL更改為正確的/userPortal/portalsForUser/:idportalsForUserCtrl函數不會觸發。 只有在我在相同的URL上按回車時,才會實例化portalsForUserCtrl並在視圖中顯示數據。 我想念什么?

$ state.go語句中有語法錯誤。

更改此:

$state.go("portalsForUser", ({ "id": userId }));

對此:

$state.go("portalsForUser", { "id": userId });

依賴項注入可能存在問題。 嘗試這個 -

resolve: {
           portalsForUser: ['userPortalService', '$stateParams', function (userPortalService, $stateParams) {
           var userId = $stateParams.id;
                 return userPortalService.getPortalsForUserPromise(userId)
                        .then(function (response) {
                            var userPortals = response.data;
                            console.log("userPortals", userPortals);
                            return userPortals;
                        });
                }] 
          }

在文檔( https://angular-ui.github.io/ui-router/site/#/api/ui.router.state。$ stateProvider)上,該方法的規范提到以下內容:

地圖對象是:

鍵-{string}:要注入控制器工廠的依賴項的名稱-{string | function}:如果為string,則它是服務的別名。 否則如果是函數,則將其注入並返回將其視為依賴項的值。 如果結果是承諾,則在將其值注入控制器之前將其解析。

以以下為例:

resolve: {
    myResolve1:
        function($http, $stateParams) {
          return $http.get("/api/foos/"+stateParams.fooID);
        }
    }

因此,我建議您將代碼更改為以下選項之一,以使其盡可能簡單,並使用chrome開發人員工具,在該方法的第一行上放置一個斷點:

resolve: {
    portalsForUser: ['userPortalService', '$stateParams', function (userPortalService, $stateParams) {
        var userId = $stateParams.id; //place your breakpoint here
        return userPortalService.getPortalsForUserPromise(userId);
    }] 
}

用$ stateParams檢查發生了什么; 由於某種原因,由於當前值並非來自url,因此由於某種原因,目前還沒有全部初始化是不可能的,因此id屬性是未定義的。 嘗試注入“ $ state”,然后查看$ state.params.id是否包含您期望的內容。 (如此處所述: https//angular-ui.github.io/ui-router/site/#/api/ui.router.state。$ state)。 看起來像這樣:

resolve: {
    portalsForUser: ['userPortalService', '$state', function (userPortalService, $state) {
        var userId = $state.params.id; //place your breakpoint here
        return userPortalService.getPortalsForUserPromise(userId);
    }] 
}

希望它不能解決您的問題,至少可以幫助您找到它。

編輯:

似乎所有以前的方法都不正確。

這是我的新方向:我使用您的竊聽器在計算機上創建了一個托管站點(使用http-server: https ://www.npmjs.com/package/http-server)。 我的版本似乎與您的版本沒有太大不同,但效果很好。 這是完整的代碼:

app.js:

(function () {
    'use strict';

    var myApp = angular.module("myApp", ["ui.router"]);

    myApp
        .config(config)
        .controller("portalsForUserCtrl", portalsForUserCtrl)
        .service('userPortalService', userPortalService)
        .controller("mainCtrl", mainCtrl)

    mainCtrl.$inject = ["userPortalService", "$state"];

    function mainCtrl(userPortalService, $state) {
        var vm = this;

        vm.clickMe = function () {
          var userId = 1;
            $state.go("portalsForUser", { "id": userId });
        }
    };

    config.$inject=["$stateProvider"];

    function config($stateProvider) {
            $stateProvider
                // PortalsForUser GET
                .state("portalsForUser", {
                    url: "/userPortal/portalsForUser/:id",
                    templateUrl: "portalsForUser.html",
                    controller: "portalsForUserCtrl as vm",
                    resolve: {
                        portalsForUser: ['userPortalService', '$stateParams', function (userPortalService, $stateParams) {
                            return userPortalService.getPortalsForUserPromise($stateParams.id).then(function(response){return response.data;});
                        }]
                    }
                })
        }

    userPortalService.$inject = ['$http', '$q', '$timeout']

    function userPortalService($http, $q, $timeout) {
        var getPortalsForUserPromise = function (id) {
            var myId=id;
            var deferred=$q.defer();

            $timeout(function(){
                deferred.resolve({data:[
                    {
                    id: 16,
                    portal: {
                        portalName: "Portal1-" + myId,
                        portalId: 1
                    }
                    },
                    {
                    id: 17,
                    portal: {
                        portalName: "Portal2-" + myId,
                        portalId: 2
                    }
                    }
                ]});
            },5000);
            return deferred.promise;
        };

        return {
            getPortalsForUserPromise: getPortalsForUserPromise
        };
    };

    portalsForUserCtrl.$inject = ['portalsForUser', 'userPortalService'];

    function portalsForUserCtrl(portalsForUser, userPortalService) {
        console.log("in portalsForUserCtrl");
        var vm = this;
        vm.portalsForUser = portalsForUser;
        console.log(portalsForUser);
    };
}());

index.html:

<html>
    <head></head>
</html>
<body ng-app="myApp">
    <!-- bower:js -->
    <script src="/bower_components/angular/angular.js"></script>
    <script src="/bower_components/angular-ui-router/release/angular-ui-router.js"></script>
    <!-- endbower -->

    <!-- inject:js -->
    <script src="app.js"></script>
    <!-- endinject -->
    <body ng-app="myApp" ng-controller="mainCtrl as vm">
        <button type="submit" class="btn btn-default" ng-click="vm.clickMe()">
            Click Me
        </button>
        <div ui-view></div>
    </body>
</body>

portalsForUser.html:

<div class="container">
    Portals For User
    <table class="table table-condensed table-striped table-bordered">
        <tbody>
            <tr>
                <th class="col-md-2">&nbsp;</th>
                <th class="col-md-4">
                    Portal Name
                </th>
            </tr>

            <tr ng-repeat="userPortal in vm.portalsForUser">
                <td>
                    {{userPortal.portal.portalName}}
                </td>
                <td class="">
                    <a class="btn btn-primary" ui-sref="goSomewhere({id: userPortal.portal.id})">
                        Go
                    </a>
                </td>
            </tr>
        </tbody>
    </table>

</div>

bower.json

{
  "name": "test",
  "description": "just a test",
  "main": "index.js",
  "authors": [
    "me"
  ],
  "license": "ISC",
  "homepage": "index.html",
  "private": true,
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "test",
    "tests"
  ],
  "dependencies": {
    "angular": "^1.5.8",
    "angular-ui-router": "ui-router#^0.3.1"
  }
}

我像其他人建議的那樣在index.html中添加了div ui-view,但是我相信這已經在您的初始項目中了。 我還試圖模擬服務,就像真正的服務一樣工作(帶有承諾和屬性數據)。

您確定自己的ui-router和angular版本正確嗎?

根據您的代碼,我已經看到您的控制器已與模塊clubSkedApp關聯,而您的配置已與myApp模塊關聯。

兩者都使用相同的模塊,或者像這樣包含控制器的模塊。

var myApp = angular.module("myApp", ["clubSkedApp","common.services", "ui.router", 'ngMessages']);

另一種方法是檢查為什么未加載狀態。 UI路由器不好引發錯誤,我發現檢查路由更改中的錯誤的唯一方法是:

myApp.run(runFn);

runFn.$inject = ['$rootScope'];

function runFn($rootScope){

  //Show the errores caused by the resolve function
  $rootScope.$on('$stateChangeError', function (event, toState, toParams, 
    fromState, fromParams, error) {
      event.preventDefault();
      console.log(error);
    });
}

我知道這個問題。 解決方案非常簡單。

您需要將<div ui-view></div>index.html中 ,以便在以后的狀態下顯示您的視圖,如下面的代碼所示。

  <body ng-app="myApp" ng-controller="mainCtrl as vm">
    <button type="submit" class="btn btn-default" ng-click="vm.clickMe()">
        Click Me
    </button>
    <div ui-view></div>
  </body>

欲了解更多信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM