如何在AngularJS中使用Laravel API

在第1部分中,我们构建了服务器部分。 现在我们可以建立我们的客户。 我们将使用AngularJS制作单页应用程序 。 我们将使用动态构建的非常基本的引导程序模板。

AngularJS徽标

规划

我们的应用程序将由三个屏幕组成。

  • 登录屏幕 :一个简单的登录屏幕。 用户将输入他们的电子邮件和密码。 如果出现问题,将显示错误。 否则,用户将被重定向到主屏幕 。 他们还可以单击“注册”链接以打开“注册” 屏幕
  • 注册屏幕 :一个简单的注册屏幕,用于在应用程序中创建一个新帐户。 指定所有必需的数据后,用户将自动登录;
  • 主屏幕 :主应用程序屏幕。 从这里,用户将能够获得他们的书籍清单,添加新书名以及更新和删除现有书名;

准备基本的前端工作环境

我们需要计划要放置应用程序的位置。 我们可以按照自己的意愿进行操作,但是对于本系列文章以及为了继续,我们将使用非常简单且“集成”的设置。

首先,我们将创建一个名为index.blade.php的基本Laravel Blade视图,它将“托管”该应用程序。 前端依赖项将由Bower处理, Bower已包含在Homestead Improvement中 。 切换到虚拟机的另一个很好的理由(如果尚未这样做)。

让我们准备一下基本视图。 在终端方面,我们去public项目和种类,在序列文件夹:

bower install jquery bootstrap angular angular - route angular - local - storage restangular

我们已经知道前三个元素: jquerybootstrapangular 。 第四个, angular-route ,将用作我们单页应用程序的路由器 。 第五个, angular-local-storage ,将用于本地存储我们的身份验证令牌。 我们将使用最后一个restangular在Angular中创建一个“资源”,该资源将通过HTTP请求与我们的服务器直接通信。

现在让我们回到Laravel。 让我们转到app/Http/routes.php文件并添加以下条目:

Route : : get ( '/' , function ( ) {
    return view ( 'index' ) ;
} ) ;

其他条目可以删除。

注意:不要混淆routes.php与文件api_routes.php文件。

让我们构建我们将要使用的Blade模板,并在resources/views创建一个名为index.blade.php的新文件。

<!DOCTYPE html>
< html lang = " en " >
    < head >
        < meta charset = " utf-8 " >
        < meta http-equiv = " X-UA-Compatible " content = " IE = edge " >
        < meta name = " viewport " content = " width = device-width, initial-scale = 1 " >

        < title > Book Wishlist Application </ title >

        < link href = " bower_components/bootstrap/dist/css/bootstrap.min.css " rel = " stylesheet " >

        < script src = " bower_components/angular/angular.min.js " > </ script >
        < script src = " bower_components/lodash/lodash.min.js " > </ script >
        < script src = " bower_components/angular-route/angular-route.min.js " > </ script >
        < script src = " bower_components/angular-local-storage/dist/angular-local-storage.min.js " > </ script >
        < script src = " bower_components/restangular/dist/restangular.min.js " > </ script >

        < style >
            
            li  {
                padding-bottom : 8 px ;
            }

        </ style >
    </ head >

    < body >
        < div class = " container " >
            < div class = " row " >
                < div class = " col-md-12 " >
                    < h1 > Book Wishlist Application </ h1 >
                </ div >
            </ div >
        </ div >

        < script src = " bower_components/jquery/dist/jquery.min.js " > </ script >
        < script src = " bower_components/bootstrap/dist/js/bootstrap.min.js " > </ script >
    </ body >
</ html >

在此文件中,我们可以找到所需的一切。

基本路由

我们将从头两个屏幕开始:“ 登录”屏幕和“ 注册”屏幕。 这将涉及我们的角度路由器。 基本原理与Laravel路由过程非常相似:我们将特定的“屏幕”分配给特定的路由。

对于每个屏幕,我们将构建一个Angular控制器。 该控制器将处理所有逻辑操作,将表示责任留给视图。

让我们在public文件夹中创建一个名为js的文件夹。 然后,我们将在其中创建一个新的app.js文件。 这将是我们的主要单页应用程序文件:

var bookWishlistApp = angular . module ( 'bookWishlistApp' , [
  'ngRoute' ,
  'bookWishlistAppControllers'
] ) ;

bookWishlistApp . config ( [ '$routeProvider' , function ( $routeProvider ) {
    
    $routeProvider .
    when ( '/login' , {
        templateUrl : 'partials/login.html' ,
        controller : 'LoginController'
    } ) .
    when ( '/signup' , {
        templateUrl : 'partials/signup.html' ,
        controller : 'SignupController'
    } ) .
    when ( '/' , {
        templateUrl : 'partials/index.html' ,
        controller : 'MainController'
    } ) .
    otherwise ( {
        redirectTo : '/'
    } ) ;

} ] ) ;

我们正在定义应用程序的路由结构。 如您所见,我们有三种可能的路线。

  • /login路径,用于“登录”屏幕;
  • /signup路线,用于“注册”屏幕;
  • / ,用于主应用程序屏幕;

声明模块,在文件的顶部,我们注入了两个依赖项。 第一个是ngRoute ,用于路由功能。 第二个是bookWishlistAppControllers ,该模块将包含我们所有的应用程序控制器。

让我们在同一文件夹中创建另一个文件,名为controllers.js

var bookWishlistAppControllers = angular . module ( 'bookWishlistAppControllers' , [ ] ) ;

bookWishlistAppControllers . controller ( 'LoginController' , [ '$scope' , '$http' , function ( $scope , $http ) {

} ] ) ;

bookWishlistAppControllers . controller ( 'SignupController' , [ '$scope' , '$http' , function ( $scope , $http ) {

} ] ) ;

bookWishlistAppControllers . controller ( 'MainController' , [ '$scope' , '$http' , function ( $scope , $http ) {
    
} ] ) ;

我们可以看到,它们现在都是空的。 我们稍后会填写。 现在,我们只想测试我们的路由系统。

让我们在public文件夹中创建另一个文件夹: partials 。 我们将在其中放置三个文件: index.htmllogin.htmlsignup.html 。 在其中每个文件中,暂时放置一些演示文本。

index.html插入:

< p > main screen </ p >

login.html

    < p > login screen </ p >

…以及在signup.html

    < p > signup screen </ p >

现在,我们更改“刀片”视图:

<!DOCTYPE html>
< html lang = " en " ng-app = " bookWishlistApp " >
    < head >
        < meta charset = " utf-8 " >
        < meta http-equiv = " X-UA-Compatible " content = " IE = edge " >
        < meta name = " viewport " content = " width = device-width, initial-scale = 1 " >

        < title > Book Wishlist Application </ title >

        < link href = " bower_components/bootstrap/dist/css/bootstrap.min.css " rel = " stylesheet " >

        < script src = " bower_components/angular/angular.min.js " > </ script >
        < script src = " bower_components/lodash/lodash.min.js " > </ script >
        < script src = " bower_components/angular-route/angular-route.min.js " > </ script >
        < script src = " bower_components/angular-local-storage/dist/angular-local-storage.min.js " > </ script >
        < script src = " bower_components/restangular/dist/restangular.min.js " > </ script >
        
        < script src = " js/app.js " > </ script >
        < script src = " js/controllers.js " > </ script >

        < style >
            
            li  {
                padding-bottom : 8 px ;
            }

        </ style >
    </ head >

    < body >

        < div class = " container " >
            < div class = " row " >
                < div class = " col-md-12 " >
                    < h1 > Book Wishlist Application </ h1 >
                </ div >
            </ div >

            < div ng-view > </ div >
        </ div >

        < script src = " bower_components/jquery/dist/jquery.min.js " > </ script >
        < script src = " bower_components/bootstrap/dist/js/bootstrap.min.js " > </ script >
    </ body >
</ html >

我们在html元素中添加了ng-app="bookWishlistApp"属性,并将ng-view属性添加到了新的div元素中。 这将是我们部件的“容器”。

我们还需要添加

< script src = " js/app.js " > </ script >
< script src = " js/controllers.js " > </ script >

行,以加载主应用程序文件和将作为依赖项注入的bookWishlistAppControllers模块。

如果我们对其进行测试,将会看到以下内容:

基本主页

Angular路由组件自动将/#/添加到URL。 现在,如果我们手动将login添加到字符串,则将得到以下信息:

路线测试

好极了! 我们的路由完美运行。

注册和登录

为了构建“登录”和“注册”屏幕,我们将一些与用户访问相关的逻辑封装在单独的userService

让我们在public/js创建一个新文件,并将其命名为services.js

var bookWishlistAppServices = angular . module ( 'bookWishlistAppServices' , [
    'LocalStorageModule'
] ) ;

bookWishlistAppServices . factory ( 'userService' , [ '$http' , 'localStorageService' , function ( $http , localStorageService ) {

    function checkIfLoggedIn ( ) {

        if ( localStorageService . get ( 'token' ) )
            return true ;
        else
            return false ;

    }

    function signup ( name , email , password , onSuccess , onError ) {

        $http . post ( '/api/auth/signup' , 
        {
            name : name ,
            email : email ,
            password : password
        } ) .
        then ( function ( response ) {

            localStorageService . set ( 'token' , response . data . token ) ;
            onSuccess ( response ) ;

        } , function ( response ) {

            onError ( response ) ;

        } ) ;

    }

    function login ( email , password , onSuccess , onError ) {

        $http . post ( '/api/auth/login' , 
        {
            email : email ,
            password : password
        } ) .
        then ( function ( response ) {

            localStorageService . set ( 'token' , response . data . token ) ;
            onSuccess ( response ) ;

        } , function ( response ) {

            onError ( response ) ;

        } ) ;

    }

    function logout ( ) {

        localStorageService . remove ( 'token' ) ;

    }

    function getCurrentToken ( ) {
        return localStorageService . get ( 'token' ) ;
    }

    return {
        checkIfLoggedIn : checkIfLoggedIn ,
        signup : signup ,
        login : login ,
        logout : logout ,
        getCurrentToken : getCurrentToken
    }

} ] ) ;

我们使用了基本的Angular $http功能来进行一些HTTP调用。 更确切地说,我们实现了:

  • 一个checkIfLoggedIn方法,用于检查令牌是否实际存在;
  • 使用名称,电子邮件和密码作为参数的signup方法。 如果注册过程顺利进行,则令牌会自动存储在本地存储中以备使用;
  • 以电子邮件和密码为参数的login方法。 如果一切顺利,令牌将存储在本地存储中;
  • logout方法以删除所存储的令牌;
  • 一个getCurrentToken方法,用于获取实际存储的令牌。 向API的受保护端点发出请求时,我们将在以后使用它;

显然,我们也必须将此文件也添加到刀片的主视图中: resources/views/index.blade.php

< script src = " js/app.js " > </ script >
< script src = " js/controllers.js " > </ script >
< script src = " js/services.js " > </ script >

现在我们有了服务,我们可以从注册屏幕开始。 这将是非常简单的一个:只是一个欢迎文本,三个文本框和一个提交按钮。

让我们从视图开始。 我们将打开public/partials/signup.html并添加:

< div class = " row " >
    < div class = " col-md-4 col-md-offset-4 " >
        < h2 > Signup </ h2 >
        < p > Welcome! If you want to sign up to our awesome service, fill this form and press on "Signup"! </ p >
        
        < hr >

        < p > < input type = " text " class = " form-control " placeholder = " Name... " ng-model = " name " required /> </ p >
        < p > < input type = " text " class = " form-control " placeholder = " Email Address... " ng-model = " email " required /> </ p >
        < p > < input type = " password " class = " form-control " placeholder = " Password... " ng-model = " password " required /> </ p >

        < hr >

        < p > < button type = " button " class = " btn btn-success form-control " ng-click = " signup() " > Signup </ button > </ p >

        < hr >

        < p > < a href = " #login " > Already signed up? < b > Log in! </ b > </ a > </ p >
    </ div >
</ div >

ng-click按钮,我们将调用控制器的signup()方法。

现在,让我们打开js/controllers.js文件,并在SignupController填充以下SignupController

bookWishlistAppControllers . controller ( 'SignupController' , [ '$scope' , '$location' , 'userService' , function ( $scope , $location , userService ) {

    $scope . signup = function ( ) {
        userService . signup (
            $scope . name , $scope . email , $scope . password ,
            function ( response ) {
                alert ( 'Great! You are now signed in! Welcome, ' + $scope . name + '!' ) ;
                $location . path ( '/' ) ;
            } ,
            function ( response ) {
                alert ( 'Something went wrong with the signup process. Try again later.' ) ;
            }
        ) ;
    }

    $scope . name = '' ;
    $scope . email = '' ;
    $scope . password = '' ;

    if ( userService . checkIfLoggedIn ( ) )
        $location . path ( '/' ) ;

} ] ) ;

让我们解释一下。

首先,我们制定了signup方法。 由于本教程已经很长了,因此我们跳过了表单验证。 它唯一要做的就是调用我们刚刚建立的userServicesignup方法。 如果一切正常,它将显示警报,并将用户重定向到主应用程序屏幕。

注意:不要忘记signup方法已经将我们的令牌保存在存储中。 因此,如果操作成功,我们将立即重定向用户。

最后,我们做一个非常基本的登录检查:

    if ( userService . checkIfLoggedIn ( ) )
        $location . path ( '/' ) ;

如果已经存在令牌,则用户将自动重定向到主页。

登录页面将非常相似。 让我们编辑public/partials/login.html

< div class = " row " >
    < div class = " col-md-4 col-md-offset-4 " >
        < h2 > Login </ h2 >
        < p > Welcome! Use this form to log into your application. </ p >
        
        < hr >

        < p > < input type = " text " class = " form-control " placeholder = " Email Address... " ng-model = " email " required /> </ p >
        < p > < input type = " password " class = " form-control " placeholder = " Password... " ng-model = " password " required /> </ p >

        < hr >

        < p > < button type = " button " class = " btn btn-success form-control " ng-click = " login() " > Login </ button > </ p >

        < hr >

        < p > < a href = " #signup " > First time here? < b > Sign up! </ b > </ a > </ p >
    </ div >
</ div >

现在,我们将在LoginController创建一个login()方法。 打开public/js/controllers.js并添加:

bookWishlistAppControllers . controller ( 'LoginController' , [ '$scope' , '$http' , '$location' , 'userService' , function ( $scope , $http , $location , userService ) {

    $scope . login = function ( ) {
        userService . login (
            $scope . email , $scope . password ,
            function ( response ) {
                $location . path ( '/' ) ;
            } ,
            function ( response ) {
                alert ( 'Something went wrong with the login process. Try again later!' ) ;
            }
        ) ;
    }

    $scope . email = '' ;
    $scope . password = '' ;

    if ( userService . checkIfLoggedIn ( ) )
        $location . path ( '/' ) ;

} ] ) ;

再一次,我们使用了userService login()方法。 如果一切顺利,用户将被重定向到主页。 否则,将显示错误警报。

图书管理

我们要做的最后一件事是实现图书管理部分。 我们将在MainController进行所有操作,从显示列表和创建过程到更新和删除。

同样,我们将为需要的有关书的持久性的所有内容(例如存储库)构建服务。 在public/js/services.js我们添加了一个新服务: bookService

bookWishlistAppServices . factory ( 'bookService' , [ 'Restangular' , 'userService' , function ( Restangular , userService ) {

    function getAll ( onSuccess , onError ) {
        Restangular . all ( 'api/books' ) . getList ( ) . then ( function ( response ) {

            onSuccess ( response ) ;
        
        } , function ( ) {

            onError ( response ) ;

        } ) ;
    }

    function getById ( bookId , onSuccess , onError ) {

        Restangular . one ( 'api/books' , bookId ) . get ( ) . then ( function ( response ) {

            onSuccess ( response ) ;

        } , function ( response ) {

            onError ( response ) ;

        } ) ;

    }

    function create ( data , onSuccess , onError ) {

        Restangular . all ( 'api/books' ) . post ( data ) . then ( function ( response ) {

            onSuccess ( response ) ;
        
        } , function ( response ) {
            
            onError ( response ) ;
        
        } ) ;

    }

    function update ( bookId , data , onSuccess , onError ) {

        Restangular . one ( "api/books" ) . customPUT ( data , bookId ) . then ( function ( response ) {
                
                onSuccess ( response ) ;

            } , function ( response ) {
                
                onError ( response ) ;
            
            }
        ) ;

    }

    function remove ( bookId , onSuccess , onError ) {
        Restangular . one ( 'api/books/' , bookId ) . remove ( ) . then ( function ( ) {

            onSuccess ( ) ;

        } , function ( response ) {

            onError ( response ) ;

        } ) ;
    }

    Restangular . setDefaultHeaders ( { 'Authorization' : 'Bearer ' + userService . getCurrentToken ( ) } ) ;

    return {
        getAll : getAll ,
        getById : getById ,
        create : create ,
        update : update ,
        remove : remove
    }

} ] ) ;

注意:不要忘记将restangular添加为模块依赖项。

如我们所见, Restangular用于处理API端点。 更准确地说,我们有五种方法。

  • getAll方法,用于检索当前用户的完整书籍清单;
  • 一个getById方法,用于在给定书ID的情况下检索特定的书;
  • create方法,用于存储新书;
  • 一种update方法,用于在给定其ID的情况下更新现有的方法;
  • remove方法,用于从列表中移除给定ID的现有书籍;

在此服务中,我们还使用已有的userServicegetCurrentToken方法处理标头及其设置。

注意:值得注意的是自定义更新方法的存在。 通常,更新流程由两个步骤组成。 获取实体,然后更新它。 我们已经在这里有了一个getById方法,因此我们不需要get部分,因为我们已经知道书的ID。 通过使用customPUT我们成功构建了更新过程的“替代”版本,而无需额外调用API服务。

我们可以从显示列表开始。 public/partials/index.html

< hr >

< div class = " pull-right " > < button type = " button " class = " btn btn-info " ng-click = " logout() " > Logout! </ button > </ div >

< div class = " clearfix " > </ div >

< hr >

< div class = " row " >
    < div class = " col-md-12 " >
        < p > You currently have < b > {{ books.length }} </ b > books in your wishlist. </ p >
        < ul >
            < li ng-repeat = " book in books " >
                < b > {{ book.title }} </ b > by < i > {{ book.author_name }} </ i >
            </ li >
        </ ul >
    </ div >
</ div >

在第一个模板中,我们仅显示书籍清单。 为了检索我们的数据,我们将在控制器中创建一个refresh方法。 在controllers.js logout方法(该方法在userService使用相同名称调用该方法)中,我们将此代码添加到MainController

bookWishlistAppControllers . controller ( 'MainController' , [ '$scope' , '$location' , 'userService' , 'bookService' , function ( $scope , $location , userService , bookService ) {

    $scope . logout = function ( ) {
        userService . logout ( ) ;
        $location . path ( '/login' ) ;
    }

    $scope . refresh = function ( ) {

        bookService . getAll ( function ( response ) {
            
            $scope . books = response ;
        
        } , function ( ) {
            
            alert ( 'Some errors occurred while communicating with the service. Try again later.' ) ;
        
        } ) ;

    }

    if ( ! userService . checkIfLoggedIn ( ) )
        $location . path ( '/login' ) ;

    $scope . books = [ ] ;

    $scope . refresh ( ) ;

} ] ) ;

我们添加了两种方法: logout调用userService具有相同名称的一种方法,并refresh 。 后者调用booksServicegetAll方法。 然后,它将结果分配给已经绑定到视图的$scope.books变量。 如果出现问题,将显示错误。

现在,我们必须实现图书创建功能。 为此,让我们返回public/partials/index.html视图。 让我们添加一个用于添加新书的模式,以及一个用于切换它的按钮。

< hr >

< div class = " pull-left " > < button type = " button " class = " btn btn-success " data-toggle = " modal " data-target = " #addBookModal " > + Add Book </ button > </ div >
< div class = " pull-right " > < button type = " button " class = " btn btn-info " ng-click = " logout() " > Logout! </ button > </ div >
< div class = " clearfix " > </ div >

< hr >

< div class = " row " >
    < div class = " col-md-12 " >
        < p > You currently have < b > {{ books.length }} </ b > books in your wishlist. </ p >
        < ul >
            < li ng-repeat = " book in books " >
                < b > {{ book.title }} </ b > by < i > {{ book.author_name }} </ i >
            </ li >
        </ ul >
    </ div >
</ div >

< div class = " modal fade " id = " addBookModal " >
  < div class = " modal-dialog " >
    < div class = " modal-content " >
      < div class = " modal-header " >
        < button type = " button " class = " close " data-dismiss = " modal " aria-label = " Close " > < span aria-hidden = " true " > &times; </ span > </ button >
        < h4 class = " modal-title " > Add a Book </ h4 >
      </ div >
      < div class = " modal-body " >
        < p > < input class = " form-control " ng-model = " currentBookTitle " placeholder = " Title... " type = " text " > </ p >
        < p > < input class = " form-control " ng-model = " currentBookAuthorName " placeholder = " Author Name... " type = " text " > </ p >
        < p > < input class = " form-control " ng-model = " currentBookPagesCount " placeholder = " Pages Count... " type = " text " > </ p >
      </ div >
      < div class = " modal-footer " >
        < button type = " button " class = " btn btn-default " data-dismiss = " modal " > Close </ button >
        < button type = " button " class = " btn btn-primary " ng-click = " create() " > Save Book </ button >
      </ div >
    </ div > <!-- /.modal-content -->
  </ div > <!-- /.modal-dialog -->
</ div > <!-- /.modal -->

现在,让我们回到MainController并实现create方法:

bookWishlistAppControllers . controller ( 'MainController' , [ '$scope' , '$location' , 'userService' , 'bookService' , function ( $scope , $location , userService , bookService ) {

    $scope . logout = function ( ) {
        userService . logout ( ) ;
        $location . path ( '/login' ) ;
    }

    $scope . create = function ( ) {

        bookService . create ( {
            title : $scope . currentBookTitle ,
            author_name : $scope . currentBookAuthorName ,
            pages_count : $scope . currentBookPagesCount
        } , function ( ) {

            $ ( '#addBookModal' ) . modal ( 'toggle' ) ;
            $scope . currentBookReset ( ) ;
            $scope . refresh ( ) ;

        } , function ( ) {

            alert ( 'Some errors occurred while communicating with the service. Try again later.' ) ;

        } ) ;

    }

    $scope . refresh = function ( ) {

        bookService . getAll ( function ( response ) {
            
            $scope . books = response ;
        
        } , function ( ) {
            
            alert ( 'Some errors occurred while communicating with the service. Try again later.' ) ;
        
        } ) ;

    }

    $scope . currentBookReset = function ( ) {
        $scope . currentBookTitle = '' ;
        $scope . currentBookAuthorName = '' ;
        $scope . currentBookPagesCount = '' ;
    }

    if ( ! userService . checkIfLoggedIn ( ) )
        $location . path ( '/login' ) ;

    $scope . books = [ ] ;

    $scope . currentBookReset ( ) ;
    $scope . refresh ( ) ;

} ] ) ;

我们的控制器不断壮大:我们可以看到create和重置所有范围变量的currentBookReset方法。 create方法显然使用bookServicecreate方法。 该应用程序现在应该已经可以正常运行了!

我们仍然必须实施图书的更新和删除。 让我们从一个简单的方法开始,即remove方法。

public/partials/index.html我们在Angular中继器中添加了一个删除按钮,该按钮将在MainController调用remove方法:

< ul >
    < li ng-repeat = " book in books " >
        < b > {{ book.title }} </ b > by < i > {{ book.author_name }} </ i > | 
        < button ng-click = " delete(book.id) " class = " btn btn-danger btn-xs " > Delete </ button >
    </ li >
</ ul >

然后,我们将remove方法添加到MainController

$scope . remove = function ( bookId ) {

    if ( confirm ( 'Are you sure to remove this book from your wishlist?' ) ) {
        bookService . remove ( bookId , function ( ) {

            alert ( 'Book removed successfully.' ) ;

        } , function ( ) {

            alert ( 'Some errors occurred while communicating with the service. Try again later.' ) ;

        } ) ;
    }

}

bookService将完成其工作。 如果出现问题,将向用户显示警报。

我们终于可以实现我们的更新功能,最后一个功能。 在public/partials/index.html视图中,我们将向转发器添加一个按钮。 这次是蓝色的“信息”。 现在,中继器将如下所示:

< ul >
    < li ng-repeat = " book in books " >
        < b > {{ book.title }} </ b > by < i > {{ book.author_name }} </ i > | 
        < button ng-click = " load(book.id) " class = " btn btn-info btn-xs " > Update </ button >
        < button ng-click = " remove(book.id) " class = " btn btn-danger btn-xs " > Remove </ button >
    </ li >
</ ul >

这是我们要添加的模式:

< div class = " modal fade " id = " updateBookModal " >
  < div class = " modal-dialog " >
    < div class = " modal-content " >
      < div class = " modal-header " >
        < button type = " button " class = " close " data-dismiss = " modal " aria-label = " Close " > < span aria-hidden = " true " > &times; </ span > </ button >
        < h4 class = " modal-title " > Update a Book </ h4 >
      </ div >
      < div class = " modal-body " >
        < input type = " hidden " ng-model = " currentBookId " />
        < p > < input class = " form-control " ng-model = " currentBookTitle " placeholder = " Title... " type = " text " > </ p >
        < p > < input class = " form-control " ng-model = " currentBookAuthorName " placeholder = " Author Name... " type = " text " > </ p >
        < p > < input class = " form-control " ng-model = " currentBookPagesCount " placeholder = " Pages Count... " type = " text " > </ p >
      </ div >
      < div class = " modal-footer " >
        < button type = " button " class = " btn btn-default " data-dismiss = " modal " > Close </ button >
        < button type = " button " class = " btn btn-primary " ng-click = " update() " > Save Changes </ button >
      </ div >
    </ div > <!-- /.modal-content -->
  </ div > <!-- /.modal-dialog -->
</ div > <!-- /.modal -->

我们还将在控制器中需要一些方法。 回到MainController我们添加:

$scope . load = function ( bookId ) {

    bookService . getById ( bookId , function ( response ) {

        $scope . currentBookId = response . book . id ;
        $scope . currentBookTitle = response . book . title ;
        $scope . currentBookAuthorName = response . book . author_name ;
        $scope . currentBookPagesCount = response . book . pages_count ;

        $ ( '#updateBookModal' ) . modal ( 'toggle' ) ;

    } , function ( ) {

        alert ( 'Some errors occurred while communicating with the service. Try again later.' ) ;

    } ) ;

}

$scope . update = function ( ) {

    bookService . update (
        $scope . currentBookId , 
        {
            title : $scope . currentBookTitle ,
            author_name : $scope . currentBookAuthorName ,
            pages_count : $scope . currentBookPagesCount
        } , 
        function ( response ) {

            $ ( '#updateBookModal' ) . modal ( 'toggle' ) ;
            $scope . currentBookReset ( ) ;
            $scope . refresh ( ) ;

        } , function ( response ) {
            alert ( 'Some errors occurred while communicating with the service. Try again later.' ) ;
        }
    ) ;
}

load方法将从API中检索图书数据,并以模式显示。 然后,在完成编辑过程之后,用户将单击“保存更改”按钮,这将调用update方法。 最后一种方法将相应地调用bookService ,并使用API​​存储编辑内容。

最终形式的控制器将如下所示

现在我们的应用程序已经完成……我们可以使用它了! 该存储大量书籍了。

工作的应用程序

是的,我爱儒勒·凡尔纳。

结论

在本系列中,我们使用了两种独立的技术以一种非常简单的方式来构建一个完整(复杂)的应用程序。 由于使用了Laravel API Boilerplate和Restangular之类的工具,我们几乎完全专注于实际的业务逻辑,而不是浪费时间进行引导。

在这一部分中,我们介绍了为Laravel API后端实现Angular前端的过程,从无到有到功能完善的应用程序。 显然,旅程并不止于此:作为练习,我的建议是实现一种机制,以检查令牌是否已过期,并创建另一个令牌来刷新它。

在以后的文章中,我们可能会研究各种不同的JS框架来实现同一件事,并判断哪个框架最简单。 关于我们应该首先尝试哪些建议?

From: https://www.sitepoint.com/how-to-consume-laravel-api-with-angularjs/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值