2013年9月14日 星期六

ASP.NET MVC與AngularJs做連動下拉選單

現在有一個ASP.NET MVCcshtml頁面,想要做一個連動下拉功能:
1.       撈取使用者資料,更新至使用者下拉選單
2.       點選使用者下拉選單,撈取出使用者喜歡過的電影名單,更新至電影下拉選單
3.       點選電影下拉選單,撈取出電影詳細資訊

功能畫面:


在後端建立要讓AngularJs$http撈取資料的action
        public ActionResult GetAllUser()
        {
            var user = _db.UserProfile.ToList().Select(x => new {
                x.UserId,
                x.NickName,
            });
            return Json(user,JsonRequestBehavior.AllowGet);
        }
        public ActionResult GetUserMovie(int userId)
        {
            var userLiked = _db.UserLinkVideo.Where(x => x.UserId == userId && x.IsLiked);
            var movie = _db.Video.Where(x => userLiked.Select(y => y.VideoId).Contains(x.VideoID));
            var query = (from u in userLiked
                        join m in movie on u.VideoId equals m.VideoID
                        select new
                        {
                            m.VideoID,
                            m.Name
                        }).ToList();
            return Json(query,JsonRequestBehavior.AllowGet);
        }
        public ActionResult GetMovie(string videoId)
        {
            var movie = _db.Video.Where(x => x.VideoID == videoId).ToList()
                .Select(x => new {
                    x.VideoID,
                    x.Name,
                    x.Story,
                    ReleaseDate = x.ReleaseDate.Value.ToString("yyyy/MM/dd"),
                    x.Picture
                }).FirstOrDefault();
            return Json(movie,JsonRequestBehavior.AllowGet);
        }

前端使用AngularJs呈現網頁:
<script>
    // var myApp = angular.module('myApp', []); 已經寫在 _Layout.cshtml
    myApp.controller('UserCtrl', function ($scope, $http) {
        $scope.isGetMovie = false; // 是否取得電影資料
        $http.get('@Url.Action("GetAllUser", "User")').success(function (data) {
            $scope.users = data;

            // 給下拉選單一個選中的值(可當預設值),這一個設定必須放在此function內,
            // 如果寫在外面則會顯示錯誤:Cannot read property '0' of undefined
            // 在此先不設定,因為要用使用頁面上的"請選擇"選項為預設值
            // $scope.user = $scope.users[0];
        });
        // 第一層選單發生變化,帶出使用者喜歡的電影
        $scope.userChange = function (user) {
            // user得到的數值為$scope.users[index];例如 : Object {UserId: 10, NickName: "ian@miniasp.com"} 
            if (user !== null) {
                // 選擇【 <option value=""></option> 】所得到的值為null
                $http.get('@Url.Action("GetUserMovie", "User")?userId=' + user.UserId).success(function (data) {
                    $scope.movies = data;
                });
            } else {
                $scope.movies = [];
            }
        };
        // 第二層選單發生變化,帶出電影詳細資料
        $scope.movieChange = function (movie) {
            if (movie !== null) {
                $http.get('@Url.Action("GetMovie", "User")?videoId=' + movie.VideoID).success(function (data) {
                    $scope.poster = data.Picture;
                    $scope.movieName = data.Name;
                    $scope.releaseDate = data.ReleaseDate;
                    $scope.isGetMovie = true;
                    console.log(data);
                });
            } else {
                $scope.isGetMovie = false;
            }
        };
    });
</script>
<h2>User</h2>
<div ng-controller="UserCtrl">
    <select ng-model="user" ng-options="u.NickName for u in users" ng-change="userChange(user)">
        <option value="" selected>-- 請選擇 --</option>
    </select>

    <select ng-model="movie" ng-options="u.Name for u in movies" ng-change="movieChange(movie)">
        <option value="" selected>-- 請選擇 --</option>
    </select>
    <!--
        因為它有 href 屬性,所以對於瀏覽器來說就是一個正常的超鏈結,因此就會有鏈結功能,然後使用者點擊後就出現 404 找不到網頁了。
        為了避免這種尷尬的問題發生,因此建議使用 ng-href 的指令來讓 AngularJS 來幫我們處理這樣的工作。
        -->
    <div ng-show="isGetMovie">
        <img ng-src="http://www.funmovie.tv/Content/pictures/files/{{poster}}?width=100" />
        <span>{{movieName}}</span>
        <span>上映日期 : {{releaseDate}}</span>
    </div>
</div>


沒有留言: