詳解 anjularjs的ui-route(多視圖、視圖嵌套、視圖傳參)

  最近整理了一下anjularjs的第三方插件ui-route,在這就以一個demo的形式講解一下。整片博客均以開頭的demo代碼爲例。下邊是個目錄,你們能夠酌情直接跳轉瀏覽。javascript

 

  1. demo的代碼css

  2. demo效果圖html

  3. ui-route是啥?有啥優點?java

  4. ui-route基礎用法jquery

  5. 如何實現多個視圖分別加載頁面app

  6. 如何實現多個視圖嵌套,視圖中套視圖ide

  7. ui-route如何實現頁面傳參函數

 

 

1. demo的代碼性能

  先看一下demo的目錄結構flex

    

  這裏說明一下,主頁面是 index;

    index裏面有 家電、美食、廚具3個頁;

      家電頁面內有 電腦、手機、電視 3個子頁面;

        手機頁面內有 華爲、蘋果、三星、vivo 4個頁面

      notice,提示頁。和家電頁面同級別

 

  再看一下具體的代碼

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>ui-route簡易demo</title>
        <style type="text/css">
            *{
                margin: 0;
                padding: 0;
                text-decoration: none;
            }
            #ui-route{
                margin: 50px auto;
                overflow: hidden;
                width: 616.6px;
            }
            ul li{
                list-style: none;
                width: 60px;
                height: 50px;
                margin: 50px 20px 10px 20px;
                cursor: pointer;
            }
            ul,.indexView,.view1,.view2{
                float: left;
                overflow: hidden;
            }
            .indexView{
                height: 350px;
                width: 400px;
                border: 1px solid black;
            }
            .view1,.view2{
                width: 80px;
                height: 175px;
                border: 1px solid #66AFE9;
                font-size: 18px;
                color: fuchsia;
                font-weight: bold;
            }
            .view1{
                text-align: center;
                word-break: break-all;
            }
            .view2{
                text-align: center;
                line-height: 177px;
            }
            .jiadian{
                width: 400px;
                list-style: none;
                display: flex;
                text-align: center;
                justify-content: space-around;
            }
            .jdView{
                width: 300px;
                height: 200px;
                border: 1px solid salmon;
                margin: 110px auto;
            }
            .phone li{
                list-style: none;
                width: 40px;
                height: 30px;
                margin: 15px;
            }
            .phoneView{
                width: 200px;
                height: 200px;
                border: 1px solid aqua;
                margin-left: 80px;
            }
            .phoneView p{
                margin: 10px 5px 15px 5px;
            }
            .noticeView{
                width: 80px;
                height: 90px;
                border-top: 1px solid royalblue;
                border-bottom: 1px solid royalblue;
            }
        </style>
    </head>
    <body ng-app="myApp" ng-controller="myControll">
        <div id="ui-route">
            <ul>
                <li ui-sref="jia_dian">家電</li>
                <li ui-sref="mei_shi">美食</li>
                <li ui-sref="chu_ju({word:'這是向家電頁面傳遞的參數word'})">廚具</li>
            </ul>
            <div class="indexView" ui-view="indexView"></div>
            <div class="view1" ui-view="view1"></div>
            <div class="view2" ui-view="view2"></div>
        </div>
    </body>
    <script type="text/javascript" src="js/jquery-1.11.3.min.js" ></script>
    <script type="text/javascript" src="js/angular.min.js" ></script>
    <script type="text/javascript" src="js/angular-ui-router.js" ></script>
    <script type="text/javascript">
        var myApp = angular.module("myApp", ["ui.router"]);
        myApp.config(function($stateProvider, $urlRouterProvider){
            $urlRouterProvider.when('indexView', "jia_dian");
            $stateProvider
        //這個是多層視圖嵌套的,一共嵌套了3層
        //這個仍是多視圖同時呈現,indexView、 view一、view2 同時呈現
                .state("jia_dian",{
        //url 第一次加載頁面時,有URL能夠自動顯示默認的頁面,沒有隻會在點擊按鈕以後才能加載視圖
        //並且刷新頁面時,若是沒有寫URL,頁面不會保存,加了,簡單刷新並不會使頁面消失
                    url:"/jia_dian",
                    views:{
                        "indexView":{
                            templateUrl:'page/jia_dian.html',
                            controller: "myControll"
                        },
                        "view1":{
                            templateUrl:'page/notice.html',
                            controller: "myControll"
                        },
                        "view2":{
                            templateUrl:'page/buy.html'
                        }
                    }
                })
                
                .state("mei_shi",{
                    url:"/mei_shi",
                    views:{
                        "indexView":{
                            templateUrl:'page/mei_shi.html',
                            controller: "myControll"
                        }
                    }
                })
                .state("chu_ju",{
                    url:"/chu_ju",
                    views:{
                        "indexView":{
                            templateUrl:'page/chu_ju.html'
                        }
                    }
                })
                
        //家電內部,電腦、手機等詳情
        //注意,視圖的嵌套,路由狀態必須是嵌套的形式,jia_dian.jd_computer。
        //若是,路由狀態只是jd_computer,這裏新加載的視圖會默認加載到父視圖indexView中
        //切記,多層嵌套必定要把每次視圖狀態名一個個點連接下去,不然會出問題
                .state("jia_dian.jd_computer",{
                    //這裏也能夠傳參數
                    url:"/jd_computer",
                    views:{
                        "jdView":{
                            controller: function($scope,$stateParams){
                                $scope.myWord = $stateParams.word;
                                console.log($stateParams);
                                console.log($stateParams.word);
                            },
                            templateUrl:'page/jia_dian/jd_computer.html'
                        }
                    }
                })
                .state("jia_dian.jd_phone",{
                    url:"/jd_phone",
                    views:{
                        "jdView":{
                            templateUrl: 'page/jia_dian/jd_phone.html',
                            controller: "myControll"
                        }
                    }
                })
                .state("jia_dian.jd_TV",{
                    url:"/jd_TV/?aa",
                    views:{
                        "jdView":{
                            controller: function($scope,$stateParams){
                                console.log($stateParams);
                                console.log($stateParams.word);
                            },
                            templateUrl: 'page/jia_dian/jd_TV.html'
                        }
                    }
                })
                
        //家電——手機 中的各類手機介紹路由
                .state("jia_dian.jd_phone.hw",{
                    url:"/jd_phone_hw",
                    views:{
                        "phoneView":{
                            templateUrl: 'page/jia_dian/jd_phone_hw.html',
                            controller: "myControll"
                        }
                    }
                })
                .state("jia_dian.jd_phone.pg",{
                    url:"/jd_phone_pg",
                    views:{
                        "phoneView":{
                            templateUrl: 'page/jia_dian/jd_phone_pg.html',
                            controller: "myControll"
                        }
                    }
                })
                .state("jia_dian.jd_phone.sx",{
                    url:"/jd_phone_sx",
                    views:{
                        "phoneView":{
                            templateUrl: 'page/jia_dian/jd_phone_sx.html',
                            controller: "myControll"
                        }
                    }
                })
                .state("jia_dian.jd_phone.vivo",{
                    url:"/jd_phone_vivo",
                    views:{
                        "phoneView":{
                            templateUrl: 'page/jia_dian/jd_phone_vivo.html',
                            controller: "myControll"
                        }
                    }
                })
                
        //右上角notice模塊路由各狀態
                .state("jia_dian.notice_in1",{
                    url:"/notice_in1",
                    views:{
                        "noticeView":{
                            templateUrl: 'page/notice/notice_in1.html',
                            controller: "myControll"
                        }
                    }
                })
                .state("jia_dian.notice_in2",{
                    url:"/notice_in2",
                    views:{
                        "noticeView":{
                            templateUrl: 'page/notice/notice_in2.html',
                            controller: "myControll"
                        }
                    }
                })
                .state("jia_dian.notice_in3",{
                    url:"/notice_in3",
                    views:{
                        "noticeView":{
                            templateUrl: 'page/notice/notice_in3.html',
                            controller: "myControll"
                        }
                    }
                })
                $urlRouterProvider.otherwise('/jia_dian');
        })
        .controller("myControll",function($scope,$state,$stateParams){
            $scope.num = 0;
            //手機頁須要的數據
            $scope.data = [
                {
                    name:"華爲 P11",
                    price:"3799 RMB",
                    color:"純潔白",
                    remark:"華爲旗艦版,徠卡雙攝,體驗極度的流暢,你值得擁有!!!"
                    
                },
                {
                    name:"iPhone8s",
                    price:"6034 RMB",
                    color:"冷傲黑",
                    remark:"蘋果旗艦機,你沒有看錯,6千多大洋,就是我,我貴,我任性!!!"
                },
                {
                    name:"三星 Glary12",
                    price:"4799 RMB",
                    color:"冷銀白",
                    remark:"看什麼看,當心我炸你啊"
                },
                {
                    name:"vivo R13",
                    price:"3099 RMB",
                    color:"高貴金",
                    remark:"高貴如我,性能還好,勝在價低,要不要試試?"
                }
            ];
            $scope.goPhone=function(){
                $state.go("jia_dian.jd_phone",{})
            };
            //經過視圖的形式,點擊切換視圖
            $scope.huan=function(){
                switch ($scope.num){
                    case 0:
                        $state.go("jia_dian.notice_in1",{});
                        break;
                    case 1:
                        $state.go("jia_dian.notice_in2",{});
                        break;
                    case 2:
                        $state.go("jia_dian.notice_in3",{});
                        break;
                    default:
                        $scope.num = 0;
                        $state.go("jia_dian.notice_in1",{});
                        break;
                }
                $scope.num++;
            };
            
            //不推薦 anjularjs 中寫 jQuery ,可是我這就偷懶了
            $("li").on("click",function(){
                $("li").css({"color":"black","font-weight":"normal"});
                $(this).css({"color":"red","font-weight":"600","font-size":"18px"});
            })
        })
    </script>
</html>
家電頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <ul class="jiadian">
            <li ui-sref="jia_dian.jd_computer">電腦</a></li>
            <li ng-click="goPhone()">手機</li>
            <li ui-sref="jia_dian.jd_TV">電視</li>
        </ul>
        <div class="jdView" ui-view="jdView"></div>
    </body>
</html>


美食頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        美食
    </body>
</html>


廚具頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        廚具
    </body>
</html>


notice頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <br />
        <div class="noticeView" ui-view="noticeView"></div>
        <br />
        <button ng-click="huan()">下一條</button>
    </body>
</html>


buy頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <button>加入購物車</button>
    </body>
</html>


電腦頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        電腦
    </body>
</html>


手機頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <ul class="phone">
            <li ui-sref="jia_dian.jd_phone.hw">華爲</li>
            <li ui-sref="jia_dian.jd_phone.pg">蘋果</li>
            <li ui-sref="jia_dian.jd_phone.sx">三星</li>
            <li ui-sref="jia_dian.jd_phone.vivo">vivo</li>
        </ul>
        <div class="phoneView" ui-view="phoneView"></div>
    </body>
</html>


電視頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        電視
    </body>
</html>


華爲頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <p>產品: {{data[0].name}}</p>
        <p>價格: {{data[0].price}}</p>
        <p>顏色: {{data[0].color}}</p>
        <p>描述: {{data[0].remark}}</p>
    </body>
</html>


蘋果頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <p>產品: {{data[1].name}}</p>
        <p>價格: {{data[1].price}}</p>
        <p>顏色: {{data[1].color}}</p>
        <p>描述: {{data[1].remark}}</p>
    </body>
</html>


三星頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <p>產品: {{data[2].name}}</p>
        <p>價格: {{data[2].price}}</p>
        <p>顏色: {{data[2].color}}</p>
        <p>描述: {{data[2].remark}}</p>
    </body>
</html>


vivo頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <p>產品: {{data[3].name}}</p>
        <p>價格: {{data[3].price}}</p>
        <p>顏色: {{data[3].color}}</p>
        <p>描述: {{data[3].remark}}</p>
    </body>
</html>


notice1頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        驚天大甩賣!!!
    </body>
</html>


notice2頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        買一送三啦!!!
    </body>
</html>


notice3頁面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        你還在等什麼!!!
    </body>
</html>

  

  以上是整個demo的全部代碼,若是有朋友以爲在這複製太麻煩,請到我博客園的  文件區  下載這個demo的源碼。

 

2. demo效果圖

    

 3. ui-route是啥?有啥優點?

    其實,anjularjs 提供了內置的ng-route,可是不怎麼好用。ui-route相對於ng-route的優點大體以下:

  (1) ui-route能夠同時加載多個ui-view,同一張頁面加載多個視圖。ng-route 只能加載一個視圖

  (2) ui-route支持 ui-view 中的頁面中也有ui-view,這樣視圖能夠嵌套

  (3) ui-route 提供了不少控制視圖的方法,讓咱們操做視圖更便捷

 

4. ui-route基礎用法

  

<div id="ui-route">
     <ul>
      <!--路由狀態跳轉的按鈕-->
<li ui-sref="jia_dian">家電</li> <li ng-click="goChuJu()">廚具</li> </ul>
    <!--打開的新頁面跳轉到的位置-->
<div class="indexView" ui-view="indexView"></div> </div> <script type="text/javascript">
  
//注入路由模塊 var myApp = angular.module("myApp", ["ui.router"]);
  
//傳入配置路由的模塊 myApp.config(function($stateProvider, $urlRouterProvider){ $urlRouterProvider.when('indexView', "jia_dian"); $stateProvider
        
//路由狀態名字,與HTML的ui-sref名字對應 .state("jia_dian",{
          
//相對的URL url:"/jia_dian", views:{
            
//加載到哪個 ui-view "indexView":{
              //新頁面路徑 templateUrl:
'page/jia_dian.html',
              
//新頁面控制器 controller: "myControll" } } }) .state("chu_ju",{ url:"/chu_ju", views:{ "indexView":{ templateUrl:'page/chu_ju.html', controller: "myControll" } } }) }) .controller("myControll",function($scope,$state,$stateParams){ $scope.goChuJu=function(){ $state.go("jia_dian.jd_phone",{}) }; }) </script>

 

 

  在HTML中給標籤添加 ui-sref="狀態名";

  定義好App以後,配置config,注入 $stateProvider ,經過state配置路由狀態;

  當前標籤被點擊時,就會加載對應頁面。

  還能夠用 $state.go("jia_dian.jd_phone",{}) 函數,直接跳轉到指定的路由狀態

  總之,ui-route 路由頁面跳轉只有  標籤價  ui-sref  和 調用  $state.go()  函數

 

5. 如何實現多個視圖分別加載頁面

  接下來講明一下如何同時加載多個視圖

 

<div id="ui-route">
    <ul>
        <li ui-sref="jia_dian">家電</li>
    </ul>
    <div class="indexView" ui-view="indexView"></div>
    <div class="view1" ui-view="view1"></div>
    <div class="view2" ui-view="view2"></div>
</div>


<script type="text/javascript">
    var myApp = angular.module("myApp", ["ui.router"]);
        myApp.config(function($stateProvider, $urlRouterProvider){
            $urlRouterProvider.when('indexView', "jia_dian");
            $stateProvider
                .state("jia_dian",{
                    url:"/jia_dian",
                    //經過view屬性進行制定ui-view的頁面分配
                    views:{
                        //視圖indexView 的插入內容
                        "indexView":{
                            templateUrl:'page/jia_dian.html',
                            controller: "myControll"
                        },
                        //視圖view1 的插入內容
                        "view1":{
                            templateUrl:'page/notice.html',
                            controller: "myControll"
                        },
                        //視圖view2 的插入內容
                        "view2":{
                            templateUrl:'page/buy.html'
                        }
                    }
                })
        })
</script>

 

  同時加載多個視圖,很簡單,只須要再HTML中分別定義好每一個視圖的名字,而後在 state 的 views 中配置每一個view該導入的頁面。這樣就能夠實現一個 index 頁面中有3個 view,並且每一個view都加載本身的HTML文件,實現本身的控制。

  可是,有個問題,同一頁面的中的 view ,同一時間只能響應一個路由狀態的變化。

  舉一個簡單的例子:

   若是,我將 家電、美食 分別加載到 view一、view2 ,這是沒問題的。刷新頁面以後,就能夠實現2個view分別顯示 家電、美食。可是若是我家電中點擊還能分別加載別的手機、電腦頁面,而我在美食點擊以後還能分別加載蘋果、香蕉頁,那這個時候就會發生衝突。路由只能相應一個狀態。好比,點擊 家電——手機,手機頁在 view 中的 jd_view 顯示了,此時再點擊 美食——蘋果,蘋果頁會在 view2顯示,可是view1的手機頁面會被刷新掉,不顯示。家電依然不會變化。

  在demo中也有這個問題,你們能夠看一下具體的圖:

    

 

6. 如何實現多個視圖嵌套,視圖中套視圖

  仍是,先看代碼:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <ul class="jiadian">
            <li ui-sref="jia_dian.jd_computer">電腦</a></li>
            <li ng-click="goPhone()">手機</li>
            <li ui-sref="jia_dian.jd_TV">電視</li>
        </ul>
        <div class="jdView" ui-view="jdView"></div>
    </body>
    <script>
    .........
        //家電內部,電腦、手機等詳情
        //注意,視圖的嵌套,路由狀態必須是嵌套的形式,jia_dian.jd_computer。
        //若是,路由狀態只是jd_computer,這裏新加載的視圖會默認加載到父視圖indexView中
        //切記,多層嵌套必定要把每次視圖狀態名一個個點連接下去,不然會出問題
                .state("jia_dian.jd_computer",{
                    //這裏也能夠傳參數
                    url:"/jd_computer",
                    views:{
                        "jdView":{
                            controller: function($scope,$stateParams){
                                $scope.myWord = $stateParams.word;
                                console.log($stateParams);
                                console.log($stateParams.word);
                            },
                            templateUrl:'page/jia_dian/jd_computer.html'
                        }
                    }
                })
                .state("jia_dian.jd_phone",{
                    url:"/jd_phone",
                    views:{
                        "jdView":{
                            templateUrl: 'page/jia_dian/jd_phone.html',
                            controller: "myControll"
                        }
                    }
                })
                .state("jia_dian.jd_TV",{
                    url:"/jd_TV/?aa",
                    views:{
                        "jdView":{
                            controller: function($scope,$stateParams){
                                console.log($stateParams);
                                console.log($stateParams.word);
                            },
                            templateUrl: 'page/jia_dian/jd_TV.html'
                        }
                    }
                })
     .........
    </script>
</html>

  嵌套也很簡單,主要是路由狀態的肯定,再就是加載到哪一個view。

  由於 電腦 頁面是在 家電頁面之中的,因此 路由狀態名必須加上他父頁面的路由,即 jia_dian.jd_computer,中間用點連接。

  注意:(1) 點 前面的名字是 父頁面的路由狀態,必定要一致

     (2)嵌套了多少層路由,路由狀態就寫都寫清楚了,不能漏

       (3)若是 不寫父頁面的路由,那頁面會直接加載到他的父頁面 所在 的view中,而且會將父頁面給刷掉,只顯示新加載的頁面

       (4)新頁面加載到哪,取決於你的views寫的啥,固然,咱們通常會在父頁面中寫個 ui-view ,讓新加載頁面顯示在裏面

  多視圖的嵌套,關鍵點 就是路由狀態名 寫對了, views寫明確了。

 

7. ui-route如何實現頁面傳參

  注意,這個路由傳遞參數是URL傳參,只能小規模的傳字符串之類的;若是是大量數據,仍是用 服務 傳遞,或者直接放在本地存儲中,方便讀取。不過這裏仍是給你們介紹一下ui-route的傳參方式。

  首先,看代碼:

<div id="ui-route">
    <ul>
        <li ui-sref="jia_dian">家電</li>
        <li ui-sref="mei_shi">美食</li>
        <li ui-sref="chu_ju({word:'這是向家電頁面傳遞的參數word'})">廚具</li>
    </ul>
    <div class="indexView" ui-view="indexView"></div>
    <div class="view1" ui-view="view1"></div>
    <div class="view2" ui-view="view2"></div>
</div>

<script type="text/javascript">
..................
    .state("jia_dian", {
            //url 第一次加載頁面時,有URL能夠自動顯示默認的頁面,沒有隻會在點擊按鈕以後才能加載視圖
            //並且刷新頁面時,若是沒有寫URL,頁面不會保存,加了,簡單刷新並不會使頁面消失
            url: "/jia_dian",
            views: {
                "indexView": {
                    templateUrl: 'page/jia_dian.html',
                    controller: "myControll"
                }
            }
        })
        .state("jia_dian.jd_phone", {
            url: "/jd_phone/?word&script&obj",
            views: {
                "jdView": {
                    templateUrl: 'page/jia_dian/jd_phone.html',
                    controller: function($scope, $stateParams) {
                        console.log($stateParams);
                        console.log($stateParams.word);
                        console.log($stateParams.obj);
                    }
                }
            }
        })
        .controller("myControll", function($scope, $state, $stateParams) {
            $scope.goPhone=function(){
                $state.go("jia_dian.jd_phone",{
                    word:"前去手機頁面",
                    script:"我將跳轉到jd_phone,即從 家電頁 到 手機頁,我在 家電的controller中寫$state.go函數,並附上參數,而後再路由中問號傳參",
                    obj:{a:"aa",b:"bb"}
                })
            };
        })
...................
</script>

 其實很簡單,就是URL傳參,步驟以下:

  1. 在父頁面HTML中     <li ui-sref="chu_ju({word:'這是向家電頁面傳遞的參數word'})">廚具</li>   這是先定義好要傳遞的變量,附好值

  2. 定義變量的另外一種方式 就是在 $state.go"jia_dian.jd_phone",{word:"前去手機頁面"})函數中,這也是在準備須要傳遞的變量

  3.上述兩種是觸發路由狀態的2種方式,分別是本身的傳參方式,都是在父頁面的HTML、控制器中。

  4. 在子頁面路由狀態中配置將傳的參數  url: "/jd_phone/?word&script&obj",  和問號傳參同樣,多個參數用 & 隔開。

  5.在跳轉到的頁面,他的控制器中注入 $stateParams ,而後就能夠打印 $stateParams 這個對象了。

  注意:聲明、賦值 是在 父頁面 作的,傳遞是在 子頁面路由中作的,使用、查看在子頁面的控制器。濾清思路就很簡單了。

 

以上,是我對 ui-route 使用的一點看法,但願對你們能有幫助。若有錯誤的地方,還請朋友們指出!!!

相關文章
相關標籤/搜索