摘要:我使用的是為這個示例應用設計接口。發起一個請求體為的請求。目前只有一個可以設置。創建一個的應用為了加強的概念我們為電影愛好者創建一個應用。我已經使用和創建了一個后端服務。創建每一個路由都對應一個。
原文地址:https://www.sitepoint.com/creating-crud-app-minutes-angulars-resource
大量的單頁應用都有CRUD操作。如果你使用angularjs創建一個CRUD操作,那么你可以利用$resource服務的優勢。$resource服務是建立在$http服務之上,并且可以使前后端用RESTful標準進行交互變得簡單的一個factory。所以,我們一起探索一下$resource,并且在angular中實現CRUD的操作。
前提$resource服務沒有打包到angularjs中。你需要下載一個獨立的文件叫angular-resource.js并且把它引入到HTML頁面中。這個文件可以從這里下載:http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular-resource.min.js。
另外,為了使用$resource你需要在主模塊中注入ngResource模塊。示例:
angular.module("mainApp",["ngResource"]); //mainApp is our main module入門
$resource和 RESTful API工作。這意味著你的 URLs 應該類似于下面的模式:
你可以創建接口使用你選擇的服務器端語言。我使用的是Node + Express + MongoDB為這個示例應用設計RESTful接口。創建好了這些URLs以后,你就可以借助于$resource與這些URLs交互。我們來看一下$resource實際上是怎么工作的。
$resource是怎么工作的?在controller/service中使用$resource需要先聲明依賴。接下來就像下面的示例一樣,在REST端調用$resource()方法。調用方法之后返回一個$resource一個可用于與REST后端交互的資源類:
angular.module("myApp.services").factory("Entry", function($resource) { return $resource("/api/entries/:id"); // Note the full endpoint address });
方法返回的是一個資源類對象,默認包含下面5種方法:
get()
query()
save()
remove()
delete()
下面我們看一下如何在controller中使用get(),query()和save()方法:
angular.module("myApp.controllers",[]); angular.module("myApp.controllers").controller("ResourceController",function($scope, Entry) { var entry = Entry.get({ id: $scope.id }, function() { console.log(entry); }); // get() 返回單個entry var entries = Entry.query(function() { console.log(entries); }); //query() 返回有的entry $scope.entry = new Entry(); //實例化一個資源類 $scope.entry.data = "some data"; Entry.save($scope.entry, function() { //data saved. do something here. }); //saves an entry. Assuming $scope.entry is the Entry object });
在上面的代碼片段中 get()方法發起/api/entries/:id的 get 請求。參數:id在被替換為$scope.id。注意get()方法返回一個空對象,當實際數據從服務器返回的時候自動填充到這個空對象。get()方法的第二個參數是回調方法,當服務器端返回數據的時候執行該回調。這是一個非常有用的技巧,因為你可以設置get()返回一個空對象,掛載到$scope,綁定視圖。當真實的數據返回且填充到對象,雙向數據綁定觸發,并且更新視圖。
query()方法發起/api/entries(注意這里沒有:id)的 get請求 并返回一個空數組。當服務器端返回數據時候填充到該數組。將該數組繼續掛在到$scope的模型上,并且在視圖上使用ng-repeat綁定。你也可以給query()傳遞一個回調方法,在數據從服務前端返回的時候執行。
save()方法發起/api/entries的 post 請求, 第一個參數是 post body。第二個參數為回調方法,當數據保存成功后執行。你應該記得$resource()方法返回的是一個資源類。所以,在我們的用例中,我們可以調用new Entry()實例化一個真正的對象,設置若干個屬性給它,最后將該對象保存到后端。
假設你只使用get()和query()在resource類上(在我們的例子中resource類是Entry)。所有非 get 請求的方法,例如save()和delete()在new Entry()實例中都能用(在這里稱為$resource實例)。不同的是這些方法都以$的開頭。所以這些有用的方法為:
$save()
$delete()
$remove
例如,$save()方法像下面一樣使用:
$scope.entry = new Entry(); //這個對象有個$save()方法 $scope.entry.$save(function() { //$scope.entry序列化為json作為post body 發送 });
我們已經實踐CRUD中的了增加,查找和刪除,剩下的最后一個修改。為了支持修改操作,我們需要像下面這樣修改我們的Entryfactory:
angular.module("myApp.services").factory("Entry", function($resource) { return $resource("/api/entries/:id", { id: "@_id" }, { update: { method: "PUT" // this method issues a PUT request } }); });
$resource的第二個 argument 明確標識需要url中:id參數的值是什么。這里將其設置為@_id,這意味著在$resource的實例中不管什么時候調用方法例如$update()和$delete(),:id的都會被設置為實例中_id的屬性值。這個是為 PUT 和 DELETE 請求使用的。注意第三個 argument,它允許我們給資源類添加自定義方法。如果該方法是一個非 get 請求,在$resource會有一個以$的同名方法。我們看一下如何使用$update方法。假設我們在controller中使用:
$scope.entry = Movie.get({ id: $scope.id }, function() { // $scope.entry 是 $scope.entry.data = "something else"; $scope.entry.$update(function() { //updated in the backend }); });
當$update()方法調用的時候,過程如下:
Angularjs 知道$update()方法會觸發 URL 為 /api/entries/:id的 PUT 請求。
讀取$scope.entry._id值,將此值賦給:id并且生成 URL。
發起一個請求體為 $scope.entity的 PUT 請求。
同樣,如果你想刪除一個entry可以像下面這么做:
$scope.entry = Movie.get({ id: $scope.id }, function() { // $scope.entry 是服務器端返回來的,是一個 Entry 的實例 $scope.entry.data = "something else"; $scope.entry.$delete(function() { //gone forever! }); });
它和 update 有著同樣的步驟,只是使用 DELETE 替換了 PUT請求類型。
我們已經覆蓋了CRUD的所有操作,但是還有一小點。$resource方法還有第4個可選擇的參數。這是一個自定義設置的值。目前只有一個 stripTrailingSlashes可以設置。它的默認值是false,這意味著它會自動刪除 URL 的最后一個 /,如果你不需要可以像下面這么做:
angular.module("myApp.services").factory("Entry", function($resource) { return $resource("/api/entries/:id", { id: "@_id" }, { update: { method: "PUT" // this method issues a PUT request } }, { stripTrailingSlashes: false }); });
順便說一句,我沒有覆蓋$resource相關的每一個東西。我們這里介紹的是最基本的,這將幫助您很快的開始一個應用的 CRUD。如果你仔細研究$resource,你可以閱讀這篇文章。
創建一個Movie的應用為了加強$resource的概念我們為電影愛好者創建一個應用。這是一個單頁應用,用戶可以新增一個電影,修改一個已存在的,最后還可以刪除。我們將使用$resource與后端 REST API 進行交互。你可以查看這個在線例子,我們將它部署在這里。
注意API允許CROS訪問(跨域資源共享),所以你可以創建一個獨立的 Angular 應用,可以使用 http://movieapp-sitepointdemo... 地址為API。你可以開發 Angular 應用不用擔心沒有后端服務。
API我已經使用 Node 和 Express創建了一個 RESTful 后端服務??聪旅娴慕貓D認識一下API接口:
我們的 AngularJS 應用采用下面的目錄結構:
movieApp /css bootstrap.css app.css /js app.js controllers.js services.js /lib angular.min.js angular-resource.min.js angular-ui-router.min.js /partials _form.html movie-add.html movie-edit.html movie-view.html movies.html index.html
注意到我們的路由使用Angular UI Router實現
創建 service 與REST后端交互像上面部分討論的一樣,我們創建一個標準的 service 使用$resource與后端 REST API 交互。這個服務定義在js/services.js中。
services.js
angular.module("movieApp.services", []).factory("Movie", function($resource) { return $resource("http://movieapp-sitepointdemos.rhcloud.com/api/movies/:id", { id: "@_id" }, { update: { method: "PUT" } }); });
這個 factory 的名字是 Movie. 我們使用的是 MongoDB,每個 movie 實例都有一個_id的屬性。rest是簡單而直接的。
現在我們已經開發好了 service,我們接下來開發 views 和 controllers。
index.html:創建應用的入口頁面index.html是我們應用的入口。我們需要將所有依賴的 scripts 和 css全部引入到頁面。我們使用 Bootstrap 來快速的開始布局。下面是index.html的內容:
The Movie App
標簽沒什么特別需要說明的。需要注意的是,ui-view指令來源于 UI Router模塊,并且作為我們視圖的容器。
創建主 Module 和 States我們主module和 states定義在js/app.js中:
app.js:
angular.module("movieApp", ["ui.router", "ngResource", "movieApp.controllers", "movieApp.services"]); angular.module("movieApp").config(function($stateProvider) { $stateProvider.state("movies", { // 展示所有movie路由 url: "/movies", templateUrl: "partials/movies.html", controller: "MovieListController" }).state("viewMovie", { //展示單個 movie 路由 url: "/movies/:id/view", templateUrl: "partials/movie-view.html", controller: "MovieViewController" }).state("newMovie", { //添加一個新 movie 路由 url: "/movies/new", templateUrl: "partials/movie-add.html", controller: "MovieCreateController" }).state("editMovie", { //修改一個movie路由 url: "/movies/:id/edit", templateUrl: "partials/movie-edit.html", controller: "MovieEditController" }); }).run(function($state) { $state.go("movies"); //當程序啟動時候默認跳轉路由 });
所以,我們的應用有以下4種狀態:
movies
viewMovie
newMovie
editMovie
每一個state由url,templateUrl和controller組成。注意到當主模塊加載的時候路由轉向 movies去展示我們系統中所有的movies。下面的截圖看一看出每個路由對應的url是什么。
所有的模板都在partials目錄下,我們挨個來看一下他們的內容。
_form.html是一個讓用戶錄入數據的的簡單表單。注意到這個表單會被movie-add.html和movie-edit.html引入,因為它們都需要用戶輸入。
下面是_form.html的內容:
模板中使用ng-model綁定不同的movie變量屬性到不同的scope的movie模型。
這個模板接收用戶輸入并且在我們的系統中保存一個新的movie,下面是具體內容:
當表單提交的時候,會觸發scope 的 addMovie()方法向后端發送一個創建movie的POST請求。
這個模板用于接收用戶收入,并且修改系統在已存在的一個movie。
這個表單一旦提交,就會觸發scope的 updateMovie()方法像向后端發送一個 PUT 請求去修改movie信息。
這個模板用于展示一個movie的詳細信息。內容如下:
Details for {{movie.title}} |
|
Movie Title | {{movie.title}} |
Director | {{movie.director}} |
Release Year | {{movie.releaseYear}} |
Movie Genre | {{movie.genre}} |
模板最后是一個編輯按鈕。點擊按鈕路由會轉向編輯狀態,并且當前編輯的movie id 會包含在$stateParams中。
這個模板用于展示系統中所有的 movie。
Add New Movie
All Movies |
|
{{movie.title}} | View Delete |
通過循環展示后端返回的每個movie對象的詳細詳細。這個也有一個添加按鈕可以將路由轉向添加狀態,觸發它可以轉向一個新的頁面并且添加一個新的movie。
在每個movie后面都有兩個操作按鈕,分別是查看和刪除。查看可以轉向movie的詳細信息頁面。刪除會將movie永久的刪除掉。
創建controllers每一個路由都對應一個controller。所以,我們總共有4個controller對應4個路由。所有的controller都在js/controllers.js中。所有的controllers都是調用我們上面討論的Movie service服務。下面看一下controllers如何調用:
controllers.js:
angular.module("movieApp.controllers", []).controller("MovieListController", function($scope, $state, popupService, $window, Movie) { $scope.movies = Movie.query(); //fetch all movies. Issues a GET to /api/movies $scope.deleteMovie = function(movie) { // Delete a movie. Issues a DELETE to /api/movies/:id if (popupService.showPopup("Really delete this?")) { movie.$delete(function() { $window.location.href = ""; //redirect to home }); } }; }).controller("MovieViewController", function($scope, $stateParams, Movie) { $scope.movie = Movie.get({ id: $stateParams.id }); //Get a single movie.Issues a GET to /api/movies/:id }).controller("MovieCreateController", function($scope, $state, $stateParams, Movie) { $scope.movie = new Movie(); //create new movie instance. Properties will be set via ng-model on UI $scope.addMovie = function() { //create a new movie. Issues a POST to /api/movies $scope.movie.$save(function() { $state.go("movies"); // on success go back to home i.e. movies state. }); }; }).controller("MovieEditController", function($scope, $state, $stateParams, Movie) { $scope.updateMovie = function() { //Update the edited movie. Issues a PUT to /api/movies/:id $scope.movie.$update(function() { $state.go("movies"); // on success go back to home i.e. movies state. }); }; $scope.loadMovie = function() { //Issues a GET request to /api/movies/:id to get a movie to update $scope.movie = Movie.get({ id: $stateParams.id }); }; $scope.loadMovie(); // Load a movie which can be edited on UI });總結
假設應用部署在localhost/movieApp,你可以通過http://localhost/movieApp/index.html訪問。如果你是一個電影愛好者,你也可以在里面添加你喜愛的電影。部署和這篇文章中用到的源碼可以在GitHub進行下載。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/80521.html
摘要:下一篇譯精通使用開發二原版書名第一章之道這一章主要是介紹,包括這個框架以及它背后的項目。幸運的是,擁有一個活躍的,支持度高的社區。另外,社區還為已經存在的工具箱里貢獻了許多有意思的工具。 下一篇:【譯】《精通使用AngularJS開發Web App》(二) 原版書名:Mastering Web Application Development with AngularJS Ch...
摘要:原文的框架以前叫做允許你使用和編寫跨平臺的桌面應用。這個教程向我們展示了如何使用和構建一個桌面應用。我們的應用看起來會是這個樣子配置開發環境是微軟的一款跨平臺代碼編輯器。是基于和微軟自身的開發的。我們需要用我們最終構建的應用來替換它。 原文:Creating Desktop Applications With AngularJS and GitHub Electron showImg(...
摘要:上一篇譯精通使用開發四下一篇譯精通使用開發六書名合作對象正如所見,提供了一種將對象組織為模塊的方式。模塊不僅可以注冊可以直接被框架所調用的對象控制器,過濾器等,還可以使用任何應用開發者所定義的對象。 上一篇:【譯】《精通使用AngularJS開發Web App》(四) 下一篇:【譯】《精通使用AngularJS開發Web App》(六) 書名:Mastering Web Applic...
摘要:在年成為最大贏家,贏得了實現的風暴之戰。和他的競爭者位列第二沒有前端開發者可以忽視和它的生態系統。他的殺手級特性是探測功能,通過檢查任何用戶的功能,以直觀的方式讓開發人員檢查所有端點。 2016 JavaScript 后起之秀 本文轉載自:眾成翻譯譯者:zxhycxq鏈接:http://www.zcfy.cc/article/2410原文:https://risingstars2016...
摘要:比如,我們可以監聽事件由實例發出,然后在任何瀏覽器中就是變化的時候都會得到通知,如下所示每一個作用域對象都會有這個方法,可以用來注冊一個作用域事件的偵聽器。這個函數所扮演的偵聽器在被調用時會有一個對象作為第一個參數。 上一篇:【譯】《精通使用AngularJS開發Web App》(二) 下一篇:【譯】《精通使用AngularJS開發Web App》(四) 書名:Mastering W...
閱讀 3687·2021-09-22 15:28
閱讀 1303·2021-09-03 10:35
閱讀 885·2021-09-02 15:21
閱讀 3487·2019-08-30 15:53
閱讀 3501·2019-08-29 17:25
閱讀 577·2019-08-29 13:22
閱讀 1563·2019-08-28 18:15
閱讀 2293·2019-08-26 13:57