AngularJS对1个前端采取AngularJS后端使用ASP.NET Web API项指标精通(三)

Home/Index.cshtml视图摘要:

首页呈现七个Moview,针对此写三个aciton方法。

 

里面,userData.isUserLoggedIn肯定是homeCinema那些module的controller,定义在了spa/home/rootCtrl.js中。

 

 

以上,username,
userData.isUserLoggedIn都以homeCinema那么些模块中rootCtrl控制器的变量。

 

//config传入名称为config的函数
//run传入名称为run的函数
//执行顺序:app.config()→app.run()→directive compile functions if found→app.controller→directive's link funciton if found
angular.module('homeCinema', ['common.core', 'common.ui'])
    .config(config)
    .run(run);


//为config函数注入参数    
config.$inject = ['$routeProvider'];

//路由设置,让controller和页面匹配
function config($routeProvider) {
    $routeProvider
        .when("/", {
            templateUrl: "scripts/spa/home/index.html",
            controller: "indexCtrl"
        })
        .when("/login", {
            templateUrl: "scripts/spa/account/login.html",
            controller: "loginCtrl"
        })
        .when("/register", {
            templateUrl: "scripts/spa/account/register.html",
            controller: "registerCtrl"
        })
        .when("/customers", {
            templateUrl: "scripts/spa/customers/customers.html",
            controller: "customersCtrl"
        })
        .when("/customers/register", {
            templateUrl: "scripts/spa/customers/register.html",
            controller: "customersRegCtrl",
            //注入到cotroller中的依赖,controller会等到resolve的动作结束后再初始化
            resolve: { isAuthenticated: isAuthenticated }
        })
        .when("/movies", {
            templateUrl: "scripts/spa/movies/movies.html",
            controller: "moviesCtrl"
        })
        .when("/movies/add", {
            templateUrl: "scripts/spa/movies/add.html",
            controller: "movieAddCtrl",
            resolve: { isAuthenticated: isAuthenticated }
        })
        .when("/movies/:id", {
            templateUrl: "scripts/spa/movies/details.html",
            controller: "movieDetailsCtrl",
            resolve: { isAuthenticated: isAuthenticated }
        })
        .when("/movies/edit/:id", {
            templateUrl: "scripts/spa/movies/edit.html",
            controller: "movieEditCtrl"
        })
        .when("/rental", {
            templateUrl: "scripts/spa/rental/rental.html",
            controller: "rentStatsCtrl"
        }).otherwise({ redirectTo: "/" });
}    

//为resolve的函数注入参数
isAuthenticated.$inject = ['membershipService', '$rootScope', '$location'];

//resolve执行的函数
function isAuthenticated(membershipService, $rootScope, $location) {
    if (!membershipService.isUserLoggedIn()) {
        $rootScope.previousState = $location.path();
        $location.path('/login');
    }
}

//为run函数注入参数
run.$inject = ['$rootScope', '$location', '$cookieStore', '$http'];

//一些初始化工作
function run($rootScope, $location, $cookieStore, $http) {
    // handle page refreshes
    //rootScope.repository
    //rootScope.repository.loggedUser
    $rootScope.repository = $cookieStore.get('repository') || {};
    if ($rootScope.repository.loggedUser) {
        $http.defaults.headers.common['Authorization'] = $rootScope.repository.loggedUser.authdata;
    }

    $(document).ready(function () {
        $(".fancybox").fancybox({
            openEffect: 'none',
            closeEffect: 'none'
        });

        $('.fancybox-media').fancybox({
            openEffect: 'none',
            closeEffect: 'none',
            helpers: {
                media: {}
            }
        });

        $('[data-toggle=offcanvas]').click(function () {
            $('.row-offcanvas').toggleClass('active');
        });
    });
}

待续~

(function (app) {
    'use strict';

    //注意这里的惯例,这里的availableMovie相当于界面上的available-movie
    app.directive('availableMovie', availableMovie);

    function availableMovie() {
        return {
            restrict: 'E',
            templateUrl: "/Scripts/spa/directives/availableMovie.html",
            link: function ($scope, $element, $attrs) {

               //getAvailbleClass供html中调用
               //attrs表示属性,注意这里的惯例:isAvailable相当于界面上的is-available
                $scope.getAvailableClass = function () {
                    if ($attrs.isAvailable === 'true')
                        return 'label label-success'
                    else
                        return 'label label-danger'
                };

                //getAvailability根据属性的布尔值返回不同的字符串
                $scope.getAvailability = function () {
                    if ($attrs.isAvailable === 'true')
                        return 'Available!'
                    else
                        return 'Not Available'
                };
            }
        }
    }

})(angular.module('common.ui'));

随之定义MoviesController,继承ApiControllerBase基类。

spa/layout/topBar.html摘要:

如上,
ApiControllerBase定义了叁个首要的方法CreateHttpResponse,不但能够拍卖请求响应,还是能够开始展览尤其处理,把尤其记录到数据库。

● 对一个前端选用AngularJS后端使用ASP.NET
Web API项目标领会(三)–主页面布局

(function (app) {
    'use strict';

    app.controller('rootCtrl', rootCtrl);

    rootCtrl.$inject = ['$scope','$location', 'membershipService','$rootScope'];


    function rootCtrl($scope, $location, membershipService, $rootScope) {

        //userData对象
        $scope.userData = {};

        //$scope.userData.displayUserInfo方法显示用户
        $scope.userData.displayUserInfo = displayUserInfo;

        //方法登出
        $scope.logout = logout;

        //$scope.userData.isUserLoggedIn,布尔类型
        //$scope.username
        function displayUserInfo() {
            $scope.userData.isUserLoggedIn = membershipService.isUserLoggedIn();

            if($scope.userData.isUserLoggedIn)
            {
                //主页面初始化的时候就定义在$rootScope.repository.loggedUser.username了
                $scope.username = $rootScope.repository.loggedUser.username;
            }
        }

        function logout() {
            membershipService.removeCredentials();
            $location.path('#/');
            $scope.userData.displayUserInfo();
        }

        $scope.userData.displayUserInfo();
    }

})(angular.module('homeCinema'));

 

spa/services/apiService.js服务用来治本GET和POST请求。

AngularJS 1

 

scripts/spa/home/index.html

 

 

 

namespace HomeCinema.Web.Infrastructure.Core
{
    public class ApiControllerBase : ApiController
    {
        protected readonly IEntityBaseRepository<Error> _errorsRepository;
        protected readonly IUnitOfWork _unitOfWork;

        public ApiControllerBase(IEntityBaseRepository<Error> errorsRepository, IUnitOfWork unitOfWork)
        {
            _errorsRepository = errorsRepository;
            _unitOfWork = unitOfWork;
        }

        public ApiControllerBase(IDataRepositoryFactory dataRepositoryFactory, IEntityBaseRepository<Error> errorsRepository, IUnitOfWork unitOfWork)
        {
            _errorsRepository = errorsRepository;
            _unitOfWork = unitOfWork;
        }

        protected HttpResponseMessage CreateHttpResponse(HttpRequestMessage request, Func<HttpResponseMessage> function)
        {
            HttpResponseMessage response = null;

            try
            {
                response = function.Invoke();
            }
            catch (DbUpdateException ex)
            {
                LogError(ex);
                response = request.CreateResponse(HttpStatusCode.BadRequest, ex.InnerException.Message);
            }
            catch (Exception ex)
            {
                LogError(ex);
                response = request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }

            return response;
        }

        //把错误报错到数据库中去
        private void LogError(Exception ex)
        {
            try
            {
                Error _error = new Error()
                {
                    Message = ex.Message,
                    StackTrace = ex.StackTrace,
                    DateCreated = DateTime.Now
                };

                _errorsRepository.Add(_error);
                _unitOfWork.Commit();
            }
            catch { }
        }
    }
}

至于缩略图的html部分就在scripts/spa/home/index.html中,具体为:

 

AngularJS 2

 

 

 

 

 

 

 

(function () {
    'use strict';

    angular.module('common.ui', ['ui.bootstrap', 'chieffancypants.loadingBar']);

})();

 

 

 

(function(app) {
    'use strict';

    app.directive('componentRating', componentRating);

    function componentRating() {
        return {
            restrict: 'A', //A说明directive以属性的方式
            link: function ($scope, $element, $attrs) {
                $element.raty({
                    score: $attrs.componentRating, //componentRating相当于界面中的component-rating,接收component-rating属性值
                    halfShow: false,
                    readOnly: $scope.isReadOnly,//表明是只读的星级
                    noRatedMsg: "Not rated yet!",
                    starHalf: "../Contentraty/star-half.png",
                    starOff: "../Contentraty/star-off.png",
                    starOn: "../Contentraty/star-on.png",
                    hints: ["Poor", "Average", "Good", "Very Good", "Excellent"],
                    click: function (score, event) {
                        //Set the model value
                        $scope.movie.Rating = score;
                        $scope.$apply();
                    }
                });
            }
        }
    }

})(angular.module('common.ui'));

 

在Movie的体现中,还定义了三个directive,用来呈现星级,在界面中按如下:

Home/Index.cshtml视图

 

AngularJS 3

 

 

(function (app) {
    'use strict';

    app.controller('indexCtrl', indexCtrl);

    indexCtrl.$inject = ['$scope','apiService', 'notificationService'];

    function indexCtrl($scope, apiService, notificationService) {

        $scope.loadingMovies = true;

        $scope.latestMovies = [];
        $scope.loadData = loadData;

        function loadData() {
            apiService.get('/api/movies/latest', null,
                        moviesLoadCompleted,
                        moviesLoadFailed);
        }

        function moviesLoadCompleted(result) {
            $scope.latestMovies = result.data;
            $scope.loadingMovies = false;
        }


        function moviesLoadFailed(response) {
            notificationService.displayError(response.data);
        }


        loadData();
    }

})(angular.module('homeCinema'));

 

 

spa/layout/sidebar.html摘要:

上述,注入了membershipService那几个服务,其余还有二个apiService,notificationService等服务被放在了common.core模块中,都以以factory的办法创立的劳务。

 

[AllowAnonymous]
[Route("latest")]
public HttpResponseMessage Get(HttpRequestMessage request)
{
    return CreateHttpResponse(request, () =>
    {
        HttpResponseMessage response = null;

        //获取6个
        var movies = _moviesRepository.GetAll().OrderByDescending(m => m.ReleaseDate).Take(6).ToList();

        //转换成视图模型
        IEnumerable<MovieViewModel> moviesVM = Mapper.Map<IEnumerable<Movie>, IEnumerable<MovieViewModel>>(movies);

        //创建响应
        response = request.CreateResponse<IEnumerable<MovieViewModel>>(HttpStatusCode.OK, moviesVM);

        return response;
    });
}

 

● 对八个前端选用AngularJS后端使用ASP.NET Web
API项指标精晓(一)–领域、Repository、瑟维斯

先是要写1个后续ApiController的类,用来拍卖登录极度。

 

 

 

 

 

界面怎样显示出来啊?在spa/app.js中的路由已经有了定义。

spa/services/notificationService.js那一个服务基于toastr.js管理全数的通报。

(function () {
    'use strict';

    angular.module('common.core', ['ngRoute', 'ngCookies', 'base64', 'angularFileUpload', 'angularValidator', 'angucomplete-alt']);

})();

 

(function (app) {
    'use strict';

    //以工厂的方式创建服务
    app.factory('notificationService', notificationService);

    function notificationService() {

        toastr.options = {
            "debug": false,
            "positionClass": "toast-top-right",
            "onclick": null,
            "fadeIn": 300,
            "fadeOut": 1000,
            "timeOut": 3000,
            "extendedTimeOut": 1000
        };

        var service = {
            displaySuccess: displaySuccess,
            displayError: displayError,
            displayWarning: displayWarning,
            displayInfo: displayInfo
        };

        return service;

        function displaySuccess(message) {
            toastr.success(message);
        }

        function displayError(error) {
            if (Array.isArray(error)) {
                error.forEach(function (err) {
                    toastr.error(err);
                });
            } else {
                toastr.error(error);
            }
        }

        function displayWarning(message) {
            toastr.warning(message);
        }

        function displayInfo(message) {
            toastr.info(message);
        }

    }

})(angular.module('common.core'));

在common.ui那个module中自定义了2个directive。在spa/layout/sideBar.directive.js

 

在界面中的适用方法:<side-bar></side-bar>

 

 

 

 

<a class="navbar-brand active" href="#/">Home Cinema</a>
<a href="#about">About</a>
<ulng-if="userData.isUserLoggedIn">
    <a href="#/">{{username}}</a>
</ul>

 

 

 

 

开创贰个关于职能的module:spa/modules/common.ui.js

 

 

 

 

再来看是还是不是出示Available
Movie的那个自定义directive,在页面中是那样使用的:

 

 

<div ng-if="loadingMovies">
    <label class="label label-primary">Loading movies...</label>
</div>

 <div ng-repeat="movie in latestMovies">
     <strong>{{movie.Title}} </strong>
     <a ng-href="../../Contentmovies/{{movie.Image}}" title="{{movie.Description | limitTo:200}}">
         <img class="media-object" height="120" ng-src="../../Contentmovies/{{movie.Image}}" alt="AngularJS 4" />
     </a>
     <available-movie is-available="{{movie.IsAvailable}}"></available-movie>
     {{movie.Description | limitTo: 70}}...</small>
     <label class="label label-info">{{movie.Genre}}</label>

     <a ng-href="{{movie.TrailerURI}}">Trailer<i class="fa fa-video-camera fa-fw"></i></a>
 </div>
(function(app) {
    'use strict';

    app.directive('topBar', topBar);

    function topBar() {
        return {
            restrict: 'E',
            replace: true,
            templateUrl: '/scripts/spa/layout/topBar.html'
        }
    }

})(angular.module('common.ui'));
<available-movie is-available="{{movie.IsAvailable}}"></available-movie>

● 对四个前端采纳AngularJS后端使用ASP.NET Web
API项目标接头(二)–正视倒置、Bundling、视图模型验证、视图模型和天地模型映射、自定义handler

制造1个有关ui的module:spa/modules/common.ui.js

● 对八个前端采用AngularJS后端使用ASP.NET Web
API项目标掌握(四)–Movie增改查以及上传图片

源码: https://github.com/chsakell/spa-webapi-angularjs
文章:http://chsakell.com/2015/08/23/building-single-page-applications-using-web-api-and-angularjs-free-e-book/

 

 

 

 

先来看控制器:spa/home/indexCtrl.js

 

最终,在spa/directives/availableMovie.html中:

 

 

homeCinema是多少个主module,正视common.ui和common.core那三个module,定义在了spa/app.js中,具体如下:

 

自定义的top bar放在了common.ui模块中,spa/layout/topBar.directive.js

<label ng-class="getAvailableClass()">{{getAvailability()}}</label>

 

 

 

side-bar

(function(app) {
    'use strict';

    app.directive('sideBar', sideBar);

    function sideBar() {
        return {
            restrict: 'E',
            replace: true,
            templateUrl: '/scripts/spa/layout/sideBar.html'
        }
    }

})(angular.module('common.ui'));

Latest
Movies 

<html ng-app="homeCinema">
    <body ng-controller="rootCtrl">
        <top-bar></top-bar>
        <side-bar></side-bar>
        <div class="page {{ pageClass }}" ng-view></div>
    </body>
</html>

点击首页Movie缩略图,弹出窗口

[Authorize(Roles = "Admin")]
[RoutePrefix("api/movies")]
public class MoviesController : ApiControllerBase
{
    private readonly IEntityBaseRepository<Movie> _moviesRepository;

    public MoviesController(IEntityBaseRepository<Movie> moviesRepository,IEntityBaseRepository<Error> _errorsRepository, IUnitOfWork _unitOfWork)
            : base(_errorsRepository, _unitOfWork)
    {
        _moviesRepository = moviesRepository;
    }

    ...
}

事实上是在spa/directives/availableMovie.directive.js中定义的。

基于类名fancybox,使用jquery语法调用jquery.fancybox.js的语法,具体调用是在app.js中调用的:

在spa/directives/componentRating.directive.js中:

 $routeProvider
    .when("/", {
        templateUrl: "scripts/spa/home/index.html",
        controller: "indexCtrl"
    })
    ...
<a ng-href="#/">Home</i>
<a ng-href="#/customers/">Customers</a>
<a ng-href="#/customers/register">Register customer</a>
<a ng-href="#/movies/">Movies</a>
<a ng-href="#/movies/add">Add movie<i class="fa fa-plus-circle fa-fw pull-right"></i></a>
<a ng-href="#/rental/">Rental history<i class="fa fa-leanpub fa-fw pull-right"></i></a>
<a ng-href="#/login" ng-if="!userData.isUserLoggedIn">Login</a>
<a ng-click="logout();" ng-if="userData.isUserLoggedIn">Logout</a>
<a class="fancybox pull-left" rel="gallery1" ng-href="../../Contentmovies/{{movie.Image}}" title="{{movie.Description | limitTo:200}}">
    <img class="media-object" height="120" ng-src="../../Contentmovies/{{movie.Image}}" alt="AngularJS 5" />
</a>

chsakell分享了二个前端选用AngularJS,后端使用ASP.NET Web API的品种。

(function (app) {
    'use strict';

    app.factory('apiService', apiService);

    apiService.$inject = ['$http', '$location', 'notificationService','$rootScope'];

    function apiService($http, $location, notificationService, $rootScope) {
        var service = {
            get: get,
            post: post
        };

        function get(url, config, success, failure) {
            return $http.get(url, config)
                    .then(function (result) {
                        success(result);
                    }, function (error) {
                        if (error.status == '401') {
                            notificationService.displayError('Authentication required.');
                            $rootScope.previousState = $location.path();
                            $location.path('/login');
                        }
                        else if (failure != null) {
                            failure(error);
                        }
                    });
        }

        function post(url, data, success, failure) {
            return $http.post(url, data)
                    .then(function (result) {
                        success(result);
                    }, function (error) {
                        if (error.status == '401') {
                            notificationService.displayError('Authentication required.');
                            $rootScope.previousState = $location.path();
                            $location.path('/login');
                        }
                        else if (failure != null) {
                            failure(error);
                        }
                    });
        }

        return service;
    }

})(angular.module('common.core'));

此处记录下对此项目标明亮。分为如下几篇:

 

也正是在根地址下,使用indexCtrl那个controller,路由到scripts/spa/home/index.html那里。

top
bar

 

上述,其实定义了二个directive,1个是available-movie,用来展现Movie的事态,或者是Available,也只怕是Not
Available;另一个是component-rating,用来呈现星级,基于
raty.js文件开发。

 

 

 

 

function run($rootScope, $location, $cookieStore, $http) {
    ...

    $(document).ready(function () {
        $(".fancybox").fancybox({
            openEffect: 'none',
            closeEffect: 'none'
        });

        ...
    });
}

 

 

 

 

相关文章