javascript - $stateParams 不断出现未定义的 angular-ui-route.js

标签 javascript angularjs

好的,我在 Controller 中有这个代码:

/* global myApp, ctrlRes */

'use strict';

myApp.controller('homeController',
    ['$scope','$state','homeDataService','companydetail',
        function ($scope, $state, homeDataService,companydetail) {

            var ctrlHome = this;
            ctrlHome.data = [];
            companydetail = [];

            ctrlHome.fetchHome = function () {
                //General Data
                homeDataService.getHomeData().then(function (result) {
                    ctrlHome.data.push(result.data.basedata.companyinfo);
                    companydetail.push(ctrlHome.data);

                    //We get list of whatever....
                    $scope.shows = homeDataService.list();
                    console.log("General: ", result.data.basedata);
                });
            };
            ctrlHome.fetchHome();


            //Redirects to a page sent into this function
            $scope.redirectToPage = function (pageToGoTo) {
                //if pageToGoTo = home, then route to /home!
                $state.go(pageToGoTo);
            };



}]);
//This is the details for HOME
myApp.controller('homeDetailController', 
    ['$scope','$state','$stateParams', 'homeDataService', 
        function($scope,$state,$stateParams, homeDataService) {

            var ctrlHmDets = this;
            ctrlHmDets.data = {};

            console.log("State Params: ", $state.params);

            //This is the part when the user selects a specifc itam
            $scope.selectedShow = homeDataService.find($stateParams.id);
            console.log("SelectedVal: " + $scope.selectedShow);
            ctrlHmDets.data.id = $scope.selectedShow;


 }]);

现在在该代码中,服务中的编码器如下:

/* global myApp, _ */
var shows = [];

myApp.factory('homeDataService', function ($http, URL) {

    //Details for the Home Page
    shows = [{
        id: 1,
        title: 'Details 1',
        name: 'Home Details',
        description1: 'This is the detail content',
        description2: 'Description content for home details',
        detailtitle: 'This is the title for home 1',
        detailbody: 'This is detail for home 1'

    },{
        id: 2,
        title: 'Details 2',
        name: 'Home Details 2',
        description1: 'This is the detail content 2',
        description2: 'Description content for home details 2',
        detailtitle: 'This is the title for home 2',
        detailbody: 'This is detail for home 3'    
    },{
        id: 3,
        title: 'Details 3',
        name: 'Home Details 3',
        description1: 'This is the detail content 3',
        description2: 'Description content for home details 3',
        detailtitle: 'This is the title for home 3',
        detailbody: 'This is detail for home 3'   
    },{
        id: 4,
        title: 'Details 4',
        name: 'Home Details 4',
        description1: 'This is the detail content 4',
        description2: 'Description content for home details 4',
        detailtitle: 'This is the title for home 4',
        detailbody: 'This is detail for home 4'    
    }];

    var getHomeData = function () {
        return $http.get(URL + 'general-junk.json')
                .success(function (data) {
                    console.log("SUCCESS!");
                    console.log("The General Junk Home: " + data.basedata.companyinfo);
                    return data.basedata.companyinfo;
                })
                .error(function (e) {
                    console.log("He\'s dead Jim!", e);
                    return e;
                });

    };
    return {

        getHomeData: getHomeData,
        list: function () {

            return shows;

        }, //This is for DETAILs if we should have them
        find: function (id) {
            return _.find(shows, function (show) {
                return show.id === id;
            });
        }
    };
});

最后在 app.js 中,我的路由是:

/* global angular */

// Code goes here
var myApp;
myApp = angular.module("myApp", [
    "ui.router"

]);


myApp.config(function ($sceDelegateProvider) {

    $sceDelegateProvider.resourceUrlWhitelist(['self', '**']);


});
myApp.config(['$stateProvider', '$urlRouterProvider',
    function ($stateProvider, $urlRouterProvider) {

        // For any unmatched url, send to /route1
        $urlRouterProvider.otherwise("home");

        $stateProvider
                .state('home', {
                    url: "/home",
                    views: {
                        "mainHeader": {
                            templateUrl: "templates/mainHeader.html"

                        },
                        "mainNav": {
                            templateUrl: "templates/mainNav.html"

                        },
                        "mainContent": {
                            templateUrl: "templates/home.html"

                        },
                        "mainFooter": {
                            templateUrl: "templates/mainFooter.html"

                        }

                    }

                })
                //When we define a state as 'parentstatename.childstatename' the convention 
                //of simply adding the period when defining the state name tells UI-Router 
                //that the child state is nested under the parent state.

                //What is really great about nested views is that the list controller just 
                //has implementation details regarding the list and the detail controller 
                //is only concerned with showing details.

                //To show how decoupled these are we only need to change the routing 
                //configuration to not nest the details and we have two separate virtual 
                //pages (one for list and one for details). More specifically, we’ll 
                //change the state name 'shows.detail' to 'detail'.

                /*.state('detail', {
                *    url: "/detail/:id",
                *    templateUrl: 'templates/home-details.html'
                *    
                *})
                *
                *      And change the link to the state from 
                *      
                *      <a ui-sref="shows.detail({id: show.id})">{{show.name}}</a> 
                *      to 
                *      <a ui-sref="detail({id: show.id})">{{show.name}}</a>
                *      on the home-details.html page or whatever page you have that
                *      link on.
                */

                .state('home.detail', {
                    url: "/detail/:id",
                    templateUrl: 'templates/home-details.html',
                    controller: function($stateParams) {
                        $stateParams.id;
                    }

                })
                .state('about', {
                    url: "/about",
                    views: {
                        "mainAbout": {
                            templateUrl: "templates/about.html"
                        }
                    }

                });
    }]);

我正在使用 angular-ui-router.js 并且我有一个

<div class="bodyStuff" ui-view></div>

注入(inject)到该 ui-view 中的 html 页面就是这样:

<h3>Hello World</h3>
<p>Some Text goes here</p>
<p><a ui-sref-active="selected" ui-sref="home.detail({id: show.id})">{{show.name}}</a>

<div class="detail" ui-view></div>

内部细节是这样的:

 <h2>Hi, I'm the detail title...</h2>
 <p>And this is what I'm all about!!!</p>

我的问题是:当我通过代码运行整个范围时,$stateParams 总是出现未定义!!!

意思是,当我在服务中调用“find”函数时,“id”参数永远不会被填充。

作为引用,这里是我得到这个的链接......

Click to view Blog

我见过 $state.params 和 $stateParams。但没有任何效果。

我做了一些研究,也发现了这个:Click to view Stackoverflow article

谢谢

更新:

下面是注入(inject)到index.html上的ui-view中的home.html

<section id="homePage">
<!-- injected Header 
<div id="header" ui-view="mainHeader"></div>-->
<!-- row -->
<div class="row" ng-controller="homeDetailController as ctrlHmDets">
    <!-- Angular Repeat... -->
    <div class="col-lg-3 col-sm-6" ng-repeat="show in shows">
        <div class="feature-widget">
            <article class="home-features-item hover">
                <div class="item-icon">
                    <i class="fa fa-html5"></i>
                </div>
                <div class="item-content">
                    <h3>{{show.title}}</h3>
                    <a ui-sref-active="selected" ui-sref="home.detail({id: show.id})">{{show.name}}</a>
                    <pre hidden="hidden">{{show | json}}</pre>
                    <p>{{show.description1}}</p>
                    <p>{{show.description2}}</p>
                </div>
            </article> <!-- home-features-item -->
        </div> <!-- feature-widget -->
    </div>
    <!-- End Repeat -->
    <div class="col-lg-12 col-sm-6">
        <!-- Detail View -->
        <div class="detail" ui-view></div>
        <!-- End Detail View --> 
    </div>
</div>

最佳答案

2015 年 8 月 9 日更新

好吧,在稍微调整一下之后,我发现它确实无法从下面的示例中正常工作。跳到底部进行调整更新,看看这个方法真的有效!!!! *

雅虎!!!我找到了解决方案here .... watch !

好的,这就是修复它并让 $stateParams 和 $state.params 同时工作的方法。

第一个 - 在您的 APP.JS 文件中的路由功能(代码)中执行此操作

            .state('home', {
                url: "/home",
                views: {
                    "mainHeader": {
                        templateUrl: "templates/mainHeader.html"

                    },
                    "mainNav": {
                        templateUrl: "templates/mainNav.html"

                    },
                    "mainContent": {
                        templateUrl: "templates/home.html"

                    },
                    "mainFooter": {
                        templateUrl: "templates/mainFooter.html"

                    },
                    //Important $stateParams Gotcha
                    //
                    //In state controllers, the $stateParams object will only contain 
                    //the params that were registered with that state. So you will not 
                    //see params registered on other states, including ancestors.
                    //
                    //This is here to fix the problem...Instead, use a resolve statement in the parent route.
                    resolve: {
                        id: ['$stateParams', function ($stateParams) {
                                return $stateParams.id; //By putting this here... (STEP 1)
                            }]
                    }
                }
            })

然后跳到下一个.state:

第 2 步:

            .state('home.detail', {
                url: "/detail/:id",
                templateUrl: 'templates/home-details.html',
                controller: function ($stateParams) {
                    $stateParams.id;  //And this down here...(MATCH TO WHAT YOU DID ABOVE. HERE!!!)
                }
            })

然后当您单击在主页面中创建的链接时运行代码:

这里...

<a ui-sref-active="selected" ui-sref="home.detail({id: show.id})">{{show.name}}</a>

结果是你在 console.log 中得到你想要的答案,在这里......

           .state('home.detail', {
                url: "/detail/:id",
                templateUrl: 'templates/home-details.html',
                controller: function ($stateParams) {
                    $stateParams.id;  //id: "1", or "2" or "n"
                }
            })

哇啦!!!有用。我会放一个小工具供大家检查。

我需要大声说出我为此组合的两个链接:

1 - http://www.funnyant.com/angularjs-ui-router/ 2 - https://github.com/angular-ui/ui-router/wiki/URL-Routing#important-stateparams-gotcha

好了,啊...我希望我能够提供帮助...感谢 dhavalcengg 的洞察力以及给我“引导”找到答案。

调整更新:

1) 好的,让我们以 app.js 为例...

    /* global angular, homeDetailsController */

    // Code goes here
    var myApp;
    myApp = angular.module("myApp", [
        "ui.router"

    ]);


    myApp.config(function ($sceDelegateProvider) {

        $sceDelegateProvider.resourceUrlWhitelist(['self', '**']);


    });
    myApp.config(['$stateProvider', '$urlRouterProvider',
        function ($stateProvider, $urlRouterProvider) {

            // For any unmatched url, send to /route1
            $urlRouterProvider.otherwise("home");

            $stateProvider
                    .state('home', {
                        url: "/home",
                        views: {
                            "mainHeader": {
                                templateUrl: "templates/mainHeader.html"

                            },
                            "mainNav": {
                                templateUrl: "templates/mainNav.html"

                            },
                            "mainContent": {
                                templateUrl: "templates/home.html"

                            },
                            "mainFooter": {
                                templateUrl: "templates/mainFooter.html"

                            },
                            //Important $stateParams Gotcha
                            //
                            //In state controllers, the $stateParams object will only contain 
                            //the params that were registered with that state. So you will not 
                            //see params registered on other states, including ancestors.
                            //
                            //This is here to fix the problem...Instead, use a resolve statement in the parent route.
                            resolve: {
                                id: ['$stateParams', function ($stateParams) {
                                        return $stateParams.id; //By putting this here...
                                    }]
                            }
                        }
                    })
                    .state('home.detail', {
                        cache: false,
                        url: "/detail/:id",
                        views: {
                            "details": {
                                templateUrl: 'templates/home-details.html',
                                controller: "homeDetailController"
                            }
                        }
                    })
                    .state('about', {
                        url: "/about",
                        views: {
                            "mainAbout": {
                                templateUrl: "templates/about.html"
                            }
                        }

                    });
        }]);

    console.log("Host name is: " + document.location.hostname);

    if (document.location.hostname === "localhost") {
        myApp.constant('URL', '/mywebsite/js/json/');
    } else if (document.location.hostname === "mywebsite.net" || "www.mywebsite.net") {
        myApp.constant('URL', '/js/json/');
    } else {
        myApp.constant('URL', '/mywebsite/js/json/');
    }


    //Registering the company for the key achievements
    //This defines and initializes a value service called company and assigns it an 
    //object with some default values.

    myApp.constant("companydetail", {
        "data": {
            "company": []

        }
    });

2) 现在是 CONTROLLERS.JS

    /* global myApp, ctrlRes */

    'use strict';

    myApp.controller('homeController',
            ['$scope', '$state', 'homeDataService', 'companydetail',
                function ($scope, $state, homeDataService, companydetail) {

                    var ctrlHome = this;
                    ctrlHome.data = [];
                    companydetail = [];

                    ctrlHome.fetchHome = function () {
                        //General Data
                        homeDataService.getHomeData().then(function (result) {
                            ctrlHome.data.push(result.data.basedata.companyinfo);
                            companydetail.push(ctrlHome.data);

                            //We get list of whatever....
                            $scope.shows = homeDataService.list();
                            console.log("General: ", result.data.basedata);
                        });
                    };
                    ctrlHome.fetchHome();


                    //Redirects to a page sent into this function
                    $scope.redirectToPage = function (pageToGoTo) {
                        //if pageToGoTo = home, then route to /home!
                        $state.go(pageToGoTo);
                    };
                }]);
    //This is the details for HOME
    myApp.controller('homeDetailController',
            ['$scope', '$stateParams', 'homeDataService',
                function ($scope, $stateParams, homeDataService) {


                var ctrlHmDets = this;
                    ctrlHmDets.data = {};
                    ctrlHmDets.data.paramsId = $stateParams.id;
                    //Call the service
                    homeDataService.find($stateParams.id);

                    console.log("From stateParams.id: " + $stateParams.id);

                    //Set the selected value
                    $scope.selectedShow = ctrlHmDets.data.id = $stateParams.id;
                    console.log("SelectedVal: " + $scope.selectedShow);

                }]);
    //This is ABOUT
    myApp.controller('aboutController', ['$scope', '$state', 'aboutDataService',
        function (aboutDataService) {
            var ctrlAbout = this;

            ctrlAbout.content = [];

            ctrlAbout.fetchHome = function () {
                //General Data
                aboutDataService.getAboutData().then(function (result) {
                    ctrlAbout.content = result.data.dets.basedata;
                    console.log("About: ", result.data.dets.basedata);
                });
            };
            ctrlAbout.fetchAbout();
        }]);

3) 接下来是 SERVICES.JS...

    /* 
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
     */
    /* global myApp, _ */
    var shows = [];

    myApp.factory('homeDataService', function ($http, URL) {

        //Details for the Home Page
        shows = [{
            id: 1,
            title: 'Details 1',
            name: 'Home Details',
            description1: 'This is the detail content',
            description2: 'Description content for home details',
            detailtitle: 'This is the title for home 1',
            detailbody: 'This is detail for home 1'

        },{
            id: 2,
            title: 'Details 2',
            name: 'Home Details 2',
            description1: 'This is the detail content 2',
            description2: 'Description content for home details 2',
            detailtitle: 'This is the title for home 2',
            detailbody: 'This is detail for home 3'    
        },{
            id: 3,
            title: 'Details 3',
            name: 'Home Details 3',
            description1: 'This is the detail content 3',
            description2: 'Description content for home details 3',
            detailtitle: 'This is the title for home 3',
            detailbody: 'This is detail for home 3'   
        },{
            id: 4,
            title: 'Details 4',
            name: 'Home Details 4',
            description1: 'This is the detail content 4',
            description2: 'Description content for home details 4',
            detailtitle: 'This is the title for home 4',
            detailbody: 'This is detail for home 4'    
        }];

        var getHomeData = function () {
            return $http.get(URL + 'general-junk.json')
                    .success(function (data) {
                        console.log("SUCCESS!");
                        console.log("The General Junk Home: ", data.basedata.companyinfo);
                        return data.basedata.companyinfo;
                    })
                    .error(function (e) {
                        console.log("He\'s dead Jim!", e);
                        return e;
                    });

        };
        return {

            getHomeData: getHomeData,
            list: function () {

                return shows;

            }, //This is for DETAILs if we should have them
            find: function (id) {
                return _.find(shows, function (show) {
                    return show.id === id;
                });
            }
        };
    });

    myApp.factory('aboutDataService', function ($http, URL) {
        var getAboutData = function () {
            return $http.get(URL + 'general-junk.json')
                    .success(function (data) {
                        console.log("SUCCESS!");
                        console.log("The About Stuff: " + data);
                        return data;
                    })
                    .error(function (e) {
                        console.log("He\'s dead Jim!", e);
                        return e;
                    });

        };
        return {
            getAboutData: getAboutData
        };
    });

5) 现在是 INDEX.HTML 页面:

    <!DOCTYPE html>
    <html id="ng-app" lang="en" ng-app="myApp">

        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">

            <title>myWesite.net</title>

            <!-- CSS -->
            <link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
            <link href="css/font-awesome.min.css" rel="stylesheet" media="screen">
            <!-- <link href="css/style.min.css" rel="stylesheet" media="screen"> -->
            <link href="css/style.css" rel="stylesheet" media="screen">
            <link href="css/wp-custom.css" rel="stylesheet" type="text/css"/> <!-- This is my custome CSS leave it out -->

            <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
            <!--[if lt IE 9]>
                <script src="js/html5shiv.js"></script>
                <script src="js/respond.min.js"></script>
            <![endif]-->
            <base href="index.html">
            <script src="js/jquery/jquery-1.10.2.min.js"></script>

            <script src="js/angular/angular.js" type="text/javascript"></script>
            <script src="js/angular/angular-ui-router.min.js" type="text/javascript"></script>

        </head>


        <body id="index">

            <div class="container" ng-controller="homeController as ctrlHome">
                <!-- Nav UI View -->
                <nav id="mainbar" class="hidden-xs" ui-view="mainNav"></nav>
                <!-- Nav UI View -->
                <div id="wrap">
                    <!-- injected header content -->
                    <div id="header" ui-view="mainHeader"></div>
                    <!-- injected main content -->
                    <div id="bodyStuff" ui-view="mainContent"></div>
                    <!-- End of Injected Content-->
                </div> <!-- wrap -->
                <footer id="footer" ui-view="mainFooter"></footer>
            </div> <!-- container -->
            <!-- underscore -->
            <script src="js/underscore.js/underscore.js" type="text/javascript"></script>
            <!-- Scripts -->
            <script src="js/bootstrap/bootstrap.min.js"></script>

            <!-- Angular -->
            <script src="js/angular/app.js" type="text/javascript"></script>
            <script src="js/angular/controllers/controllers.js" type="text/javascript"></script>
            <script src="js/angular/directives/directives.js" type="text/javascript"></script>
            <script src="js/angular/services/data-service.js" type="text/javascript"></script>


        </body>

    </html>

6) 现在让我们检查一下 HOME.HTML 文件

    <section id="homePage">
        <!-- injected Header 
        <div id="header" ui-view="mainHeader"></div>-->
        <!-- row -->
        <div class="row">
            <!-- Angular Repeat... -->
            <div class="col-lg-3 col-sm-6" ng-repeat="show in shows">
                <div class="feature-widget">
                    <article class="home-features-item hover">
                        <div class="item-icon">
                            <i class="fa fa-html5"></i>
                        </div>
                        <div class="item-content">
                            <h3>{{show.title}}</h3>
                            <a ui-sref-active="selected" ui-sref="home.detail({id: show.id})">{{show.name}}</a>
                            <p>{{show.description1}}</p>
                            <p>{{show.description2}}</p>
                            <pre hidden="hidden">{{show | json}}</pre>
                        </div>
                    </article> <!-- home-features-item -->
                </div> <!-- feature-widget -->
            </div>
            <!-- End Repeat -->
            <div class="col-lg-12 col-sm-6">
                <!-- Detail View -->
                <div class="detail" ui-view="details"></div>
                <!-- End Detail View --> 
            </div>
        </div>
    </section>

7) 最后是 HOME-DETAILS.HTML 文件...

    <h3>{{shows[selectedShow - 1].detailtitle}}</h3>
    <p>{{shows[selectedShow - 1].detailbody}}</p>
    <pre hidden="hidden">{{selectedShow - 1 | json}}</pre>

结果非常漂亮。

这是对我上面从 Craig Craig McKeachiein 的博客和播客中引用的文章的增强。他对我的启发值得称赞。

这是来自 CreativeMarket 上的模板我想将 Angular 添加到其中。

关于javascript - $stateParams 不断出现未定义的 angular-ui-route.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31873457/

相关文章:

javascript - 在 javascript 中使用相同的参数组成链式函数

javascript - 将音频播放器分解为 MVC 结构

javascript - Angular JS 错误 angular.js :38Uncaught Error: [$injector:modulerr]

javascript - 如何设置 Angular 路线参数的可接受值?

javascript - 如何使用 AngularJS 获得 promise 结果

javascript - 什么是 CSS :before, 的最佳降级:在较旧的 IE 中伪造之后

javascript - 如何通过滚动在页面的特定部分执行 jquery 插件?

javascript - Angular : Unable to find the index of an array

javascript - 替代异步标注的 promise ?

javascript - JS中获取JSESSIONID cookie值