apeescape2.com
  • メイン
  • ヒントとツール
  • ブランドデザイン
  • トレンド
  • 投資家と資金調達
Webフロントエンド

AngularJSとPlayFrameworkを使用した最新のWebアプリケーションの構築

特に最新のWebアプリケーションの構築に関しては、適切な目的に適切なツールを選択することは大いに役立ちます。私たちの多くは、AngularJSと、それが堅牢なWebアプリケーションフロントエンドの開発をいかに簡単にするかをよく知っています。多くの人がこの人気のあるWebフレームワークの使用に反対するでしょうが、それは確かに提供するものがたくさんあり、 適切な選択 幅広いニーズに対応します。一方、バックエンドで使用するコンポーネントは、全体的なユーザーエクスペリエンスに影響を与えるため、Webアプリケーションのパフォーマンスに大きく影響します。 演奏する JavaとScala用の高速Webフレームワークです。これは、軽量でステートレスなWebフレンドリーなアーキテクチャに基づいており、RailsやDjangoと同様のMVCパターンと原則に従います。

anglejsとplayフレームワークを備えたWebアプリケーション

この記事では、AngularJSとPlayを使用して、基本認証メカニズムと投稿やコメントを作成する機能を備えたシンプルなブログアプリケーションを構築する方法を見ていきます。 AngularJS開発 、 一部で Twitterブートストラップ これにより、PlayベースのRESTAPIバックエンドに加えて単一ページのアプリケーションエクスペリエンスを強化できます。



Webアプリケーション-はじめに

AngularJSアプリケーションスケルトン

AngularJSおよびPlayアプリは、それに応じてクライアントおよびサーバーディレクトリに常駐します。今のところ、「クライアント」ディレクトリを作成します。

mkdir -p blogapp/client

AngularJSアプリケーションスケルトンを作成するために、素晴らしいスキャフォールディングツールであるYeomanを使用します。 ヨーマンのインストールは簡単です 。これを使用して、単純な骨格のAngularJSアプリケーションをスキャフォールディングする方がおそらくさらに簡単です。

cd blogapp/client yo angular

2番目のコマンドを実行すると、選択する必要のあるいくつかのオプションが続きます。このプロジェクトでは、「Sass(コンパス付き)」は必要ありません。次のAngularJSプラグインとともにBoostrapが必要になります。

  • angle-animate.js
  • 角度-cookies.js
  • angle-resource.js
  • angle-route.js
  • 角度-sanitize.js
  • angle-touch.js

この時点で、選択を確定すると、端末にNPMとBowerの出力が表示されるようになります。ダウンロードが完了し、パッケージがインストールされると、AngularJSアプリケーションスケルトンを使用できるようになります。

PlayFrameworkアプリケーションスケルトン

新しいPlayアプリケーションを作成する公式の方法には、TypesafeActivatorツールの使用が含まれます。使用する前に、ダウンロードしてコンピュータにインストールする必要があります。 Mac OSを使用していて、Homebrewを使用している場合は、次の1行のコマンドでこのツールをインストールできます。

brew install typesafe-activator

コマンドラインからPlayアプリケーションを作成するのはとても簡単です。

cd blogapp/ activator new server play-java cd server/

IDEへのインポート

EclipseやIntelliJなどのIDEにアプリケーションをインポートするには、アプリケーションを「Eclipse化」または「理想化」する必要があります。これを行うには、次のコマンドを実行します。

activator

新しいプロンプトが表示されたら、「eclipse」または「idea」と入力し、Enterキーを押して、それぞれEclipseまたはIntelliJのアプリケーションコードを準備します。

PHP7の新機能

簡潔にするために、この記事ではプロジェクトをIntelliJにインポートするプロセスのみを取り上げます。それをEclipseにインポートするプロセスも同様に単純でなければなりません。プロジェクトをIntelliJにインポートするには、「ファイル->新規」の下にある「既存のソースからのプロジェクト…」オプションをアクティブ化することから始めます。次に、build.sbtファイルを選択し、「OK」をクリックします。次のダイアログでもう一度[OK]をクリックすると、IntelliJはPlayアプリケーションをSBTプロジェクトとしてインポートし始めるはずです。

Typesafe Activatorには、グラフィカルユーザーインターフェイスも付属しています。 この骨格アプリケーションコードを作成します 。

PlayアプリケーションをIntelliJにインポートしたので、AngularJSアプリケーションもワークスペースにインポートする必要があります。個別のプロジェクトとして、またはPlayアプリケーションが存在する既存のプロジェクトへのモジュールとしてインポートできます。

ここでは、Angularアプリケーションをモジュールとしてインポートします。 「ファイル」メニューの下で、「新規->既存のソースからのモジュール…」オプションを選択します。ダイアログから「クライアント」ディレクトリを選択し、「OK」をクリックします。次の2つの画面で、それぞれ「次へ」と「完了」をクリックします。

ローカルサーバーの生成

この時点で、IDEからAngularJSアプリケーションをGruntタスクとして開始できるはずです。クライアントフォルダを展開し、Gruntfile.jsを右クリックします。ポップアップメニューで「GruntTasksを表示」を選択します。 「Grunt」というラベルの付いたパネルが表示され、タスクのリストが示されます。

ローカルサーバーの生成

アプリケーションの提供を開始するには、「提供」をダブルクリックします。これにより、すぐにデフォルトのWebブラウザーが開き、ローカルホストアドレスを指すようになります。 Yeomanのロゴが付いたスタブAngularJSページが表示されます。

次に、バックエンドアプリケーションサーバーを起動する必要があります。先に進む前に、いくつかの問題に対処する必要があります。

  1. デフォルトでは、AngularJSアプリケーション(Yeomanによってブートストラップされた)とPlayアプリケーションの両方がポート9000で実行しようとします。
  2. 本番環境では、両方のアプリケーションが1つのドメインで実行される可能性が高く、それに応じてNginxを使用してリクエストをルーティングします。ただし、開発モードでは、これらのアプリケーションの1つのポート番号を変更すると、Webブラウザーはそれらを異なるドメインで実行されているかのように扱います。

これらの問題の両方を回避するには、Gruntプロキシを使用して、PlayアプリケーションへのすべてのAJAXリクエストがプロキシされるようにするだけです。これにより、本質的に、これらのアプリケーションサーバーは両方とも同じ見かけのポート番号で使用できるようになります。

まず、Playアプリケーションサーバーのポート番号を9090に変更します。これを行うには、[実行]-> [構成の編集]をクリックして[構成の実行/デバッグ]ウィンドウを開きます。次に、「UrlToOpen」フィールドのポート番号を変更します。 「OK」をクリックしてこの変更を承認し、ウィンドウを閉じます。 「実行」ボタンをクリックすると、依存関係の解決プロセスが開始されます。このプロセスのログが表示され始めます。

ローカルサーバーの生成

完了すると、Webブラウザでhttp:// localhost:9090に移動でき、数秒でPlayアプリケーションが表示されるはずです。 Gruntプロキシを構成するには、最初にNPMを使用して小さなNode.jsパッケージをインストールする必要があります。

cd blogapp/client npm install grunt-connect-proxy --save-dev

次に、Gruntfile.jsを微調整する必要があります。そのファイルで、「接続」タスクを見つけ、その後に「プロキシ」キー/値を挿入します。

proxies: [ { context: '/app', // the context of the data service host: 'localhost', // wherever the data service is running port: 9090, // the port that the data service is running on changeOrigin: true } ],

Gruntは、「/ app / *」へのすべてのリクエストをバックエンドのPlayアプリケーションにプロキシするようになりました。これにより、バックエンドへのすべての呼び出しをホワイトリストに登録する必要がなくなります。さらに、livereloadの動作を微調整する必要もあります。

livereload: { options: { open: true, middleware: function (connect) { var middlewares = []; // Setup the proxy middlewares.push(require('grunt-connect-proxy/lib/utils').proxyRequest); // Serve static files middlewares.push(connect.static('.tmp')); middlewares.push(connect().use( '/bower_components', connect.static('./bower_components') )); middlewares.push(connect().use( '/app/styles', connect.static('./app/styles') )); middlewares.push(connect.static(appConfig.app)); return middlewares; } } },

最後に、新しい依存関係「 ’configureProxies:server」を「serve」タスクに追加する必要があります。

grunt.registerTask('serve', 'Compile then start a connect web server', function (target) { if (target === 'dist') { return grunt.task.run(['build', 'connect:dist:keepalive']); } grunt.task.run([ 'clean:server', 'wiredep', 'concurrent:server', 'autoprefixer:server', 'configureProxies:server', 'connect:livereload', 'watch' ]); });

Gruntを再起動すると、プロキシが実行されていることを示す次の行がログに記録されます。

Running 'autoprefixer:server' (autoprefixer) task File .tmp/styles/main.css created. Running 'configureProxies:server' (configureProxies) task Running 'connect:livereload' (connect) task Started connect web server on http://localhost:9000

サインアップフォームの作成

まず、ブログアプリケーションのサインアップフォームを作成します。これにより、すべてが正常に機能していることを確認することもできます。 Yeomanを使用して、サインアップコントローラーを作成し、AngularJSで表示できます。

yo angular:controller signup yo angular:view signup

次に、この新しく作成されたビューを参照するようにアプリケーションのルーティングを更新し、自動生成された冗長な「about」コントローラーとビューを削除する必要があります。ファイル「app / scripts / app.js」内から、「app / scripts / controllers /about.js」および「app / views / about.html」への参照を削除し、次のようにします。

.config(function ($routeProvider) { $routeProvider .when('/', { templateUrl: 'views/main.html', controller: 'MainCtrl' }) .when('/signup', { templateUrl: 'views/signup.html', controller: 'SignupCtrl' }) .otherwise({ redirectTo: '/' });

同様に、「app / index.html」ファイルを更新して冗長リンクを削除し、サインアップページにリンクを追加します。

  • Home
  • Signup

また、「about.js」のスクリプトタグを削除します。

Email Password Sign up!

次に、「signup.html」ファイルにフォームを追加します。

angular.module('clientApp') .controller('SignupCtrl', function ($scope, $http, $log) { $scope.signup = function() { var payload = { email : $scope.email, password : $scope.password }; $http.post('app/signup', payload) .success(function(data) { $log.debug(data); }); }; });

フォームをAngularコントローラーで処理する必要があります。 「app.js」のルーティングロジックは、ビューが読み込まれる前にコントローラーを自動的に起動するため、ビューに「ng-controller」属性を具体的に追加する必要がないことに注意してください。このフォームを接続するために必要なのは、$ scopeで定義された適切な「サインアップ」関数を用意することだけです。これは、「signup.js」ファイルで実行する必要があります。

public static Result signup() { return ok('Success!'); }

次に、Chromeデベロッパーコンソールを開き、[ネットワーク]タブに切り替えて、登録フォームを送信してみましょう。

AngularPlayサインアップフォームの例

Playバックエンドが「アクションが見つかりません」というエラーページで自然に応答することがわかります。まだ実装されていないため、これは予想されます。しかし、それが意味するのは、Gruntプロキシのセットアップが正しく機能しているということです。

次に、基本的にPlayアプリケーションコントローラーのメソッドである「アクション」を追加します。 「app / controllers」パッケージのクラス「Application」に、新しいメソッド「signup」を追加します。

POST /app/signup controllers.Application.signup

次に、ファイル「conf / routers」を開き、次の行を追加します。

db.default.driver=org.h2.Driver db.default.url='jdbc:h2:mem:play' db.default.user=sa db.default.password='' ... ebean.default='models.*'

最後に、Webブラウザhttp:// localhost:9000 /#/ signupに戻ります。今回は「送信」ボタンをクリックすると、別の結果が得られるはずです。

ブラウザでのAngularPlayサインアップフォームの例

サインアップメソッドで記述したハードコードされた値が返されるはずです。その場合は、開発環境の準備が整い、AngularアプリケーションとPlayアプリケーションの両方で機能しているので、次に進む準備ができています。

PlayでのEbeanモデルの定義

モデルを定義する前に、まずデータストアを選択しましょう。この記事では、H2インメモリデータベースを使用します。これを有効にするには、ファイル「application.conf」で次の行を見つけてコメントを解除します。

applyEvolutions.default=true

そして、次の行を追加します。

// User.java @Entity public class User extends Model { @Id public Long id; @Column(length = 255, unique = true, nullable = false) @Constraints.MaxLength(255) @Constraints.Required @Constraints.Email public String email; @Column(length = 64, nullable = false) private byte[] shaPassword; @OneToMany(cascade = CascadeType.ALL) @JsonIgnore public List posts; public void setPassword(String password) { this.shaPassword = getSha512(password); } public void setEmail(String email) { this.email = email.toLowerCase(); } public static final Finder find = new Finder( Long.class, User.class); public static User findByEmailAndPassword(String email, String password) { return find .where() .eq('email', email.toLowerCase()) .eq('shaPassword', getSha512(password)) .findUnique(); } public static User findByEmail(String email) { return find .where() .eq('email', email.toLowerCase()) .findUnique(); } public static byte[] getSha512(String value) { try { return MessageDigest.getInstance('SHA-512').digest(value.getBytes('UTF-8')); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } }

私たちのブログドメインモデルはかなり単純です。まず、投稿を作成できるユーザーがいます。次に、サインインしたユーザーが各投稿にコメントを付けることができます。 Ebeanモデルを作成しましょう。

ユーザー

// BlogPost.java @Entity public class BlogPost extends Model { @Id public Long id; @Column(length = 255, nullable = false) @Constraints.MaxLength(255) @Constraints.Required public String subject; @Column(columnDefinition = 'TEXT') @Constraints.Required public String content; @ManyToOne public User user; public Long commentCount; @OneToMany(cascade = CascadeType.ALL) public List comments; public static final Finder find = new Finder( Long.class, BlogPost.class); public static List findBlogPostsByUser(final User user) { return find .where() .eq('user', user) .findList(); } public static BlogPost findBlogPostById(final Long id) { return find .where() .eq('id', id) .findUnique(); } }

BlogPost

// PostComment.java @Entity public class PostComment extends Model { @Id public Long id; @ManyToOne @JsonIgnore public BlogPost blogPost; @ManyToOne public User user; @Column(columnDefinition = 'TEXT') public String content; public static final Finder find = new Finder( Long.class, PostComment.class); public static List findAllCommentsByPost(final BlogPost blogPost) { return find .where() .eq('post', blogPost) .findList(); } public static List findAllCommentsByUser(final User user) { return find .where() .eq('user', user) .findList(); } }

コメントを投稿

// Application.java public static Result signup() { Form signUpForm = Form.form(SignUp.class).bindFromRequest(); if ( signUpForm.hasErrors()) { return badRequest(signUpForm.errorsAsJson()); } SignUp newUser = signUpForm.get(); User existingUser = User.findByEmail(newUser.email); if(existingUser != null) { return badRequest(buildJsonResponse('error', 'User exists')); } else { User user = new User(); user.setEmail(newUser.email); user.setPassword(newUser.password); user.save(); session().clear(); session('username', newUser.email); return ok(buildJsonResponse('success', 'User created successfully')); } } public static class UserForm { @Constraints.Required @Constraints.Email public String email; } public static class SignUp extends UserForm { @Constraints.Required @Constraints.MinLength(6) public String password; } private static ObjectNode buildJsonResponse(String type, String message) { ObjectNode wrapper = Json.newObject(); ObjectNode msg = Json.newObject(); msg.put('message', message); wrapper.put(type, msg); return wrapper; }

実際のサインアップアクション

それでは、ユーザーがサインアップできるように、最初の実際のアクションを作成しましょう。

yo angular:service alerts

このアプリで使用される認証は非常に基本的なものであり、本番環境での使用はお勧めしません。

興味深いのは、Playフォームを使用してサインアップフォームを処理していることです。サインアップフォームクラスにいくつかの制約を設定します。検証は、明示的な検証ロジックを必要とせずに自動的に行われます。

WebブラウザでAngularJSアプリケーションに戻り、もう一度[送信]をクリックすると、サーバーが適切なエラーで応答することがわかります。これらのフィールドは必須です。

プレイフォームを送信する

AngularJSでのサーバーエラーの処理

そのため、サーバーからエラーが発生しますが、アプリケーションユーザーは何が起こっているのかわかりません。少なくとも私たちにできることは、ユーザーにエラーを表示することです。理想的には、発生しているエラーの種類を理解し、ユーザーフレンドリーなメッセージを表示する必要があります。エラーの表示に役立つ簡単なアラートサービスを作成しましょう。

まず、Yeomanを使用してサービステンプレートを生成する必要があります。

angular.module('clientApp') .factory('alertService', function($timeout) { var ALERT_TIMEOUT = 5000; function add(type, msg, timeout) { if (timeout) { $timeout(function(){ closeAlert(this); }, timeout); } else { $timeout(function(){ closeAlert(this); }, ALERT_TIMEOUT); } return alerts.push({ type: type, msg: msg, close: function() { return closeAlert(this); } }); } function closeAlert(alert) { return closeAlertIdx(alerts.indexOf(alert)); } function closeAlertIdx(index) { return alerts.splice(index, 1); } function clear(){ alerts = []; } function get() { return alerts; } var service = { add: add, closeAlert: closeAlert, closeAlertIdx: closeAlertIdx, clear: clear, get: get }, alerts = []; return service; } );

次に、このコードを「alerts.js」に追加します。

yo angular:controller alerts

それでは、アラートを担当する別のコントローラーを作成しましょう。

angular.module('clientApp') .controller('AlertsCtrl', function ($scope, alertService) { $scope.alerts = alertService.get(); }); bower install angular-bootstrap --save

次に、実際に素晴らしいBootstrapエラーメッセージを表示する必要があります。最も簡単な方法は Angular UI 。 Bowerを使用してインストールできます。

angular .module('clientApp', [ 'ngAnimate', 'ngCookies', 'ngResource', 'ngRoute', 'ngSanitize', 'ngTouch', 'ui.bootstrap' ])

「app.js」にAngularUIモジュールを追加します。

{{ alert.msg }}

「index.html」ファイルにアラートディレクティブを追加しましょう。

angular.module('clientApp') .controller('SignupCtrl', function ($scope, $http, $log, alertService, $location, userService) { $scope.signup = function() { var payload = { email : $scope.email, password : $scope.password }; $http.post('app/signup', payload) .error(function(data, status) { if(status === 400) { angular.forEach(data, function(value, key) { if(key === 'email' || key === 'password') { alertService.add('danger', key + ' : ' + value); } else { alertService.add('danger', value.message); } }); } if(status === 500) { alertService.add('danger', 'Internal server error!'); } }) }; });

最後に、SignUpコントローラーを更新する必要があります。

yo angular:view dashboard yo angular:controller dashboard

ここで、空のフォームを再度送信すると、フォームの上にエラーが表示されます。

AngularPlayエラー

エラーが処理されたので、ユーザーのサインアップが成功したときに何かをする必要があります。ユーザーをダッシュ​​ボードページにリダイレクトして、投稿を追加することができます。しかし、最初に、それを作成する必要があります。

angular.module('clientApp') .controller('SignupCtrl', function ($scope, $http, $log, alertService, $location) { // .. .success(function(data) { if(data.hasOwnProperty('success')) { $location.path('/dashboard'); } });

「signup.js」コントローラーのサインアップメソッドを変更して、成功するとユーザーをリダイレクトするようにします。

.when('/dashboard', { templateUrl: 'views/dashboard.html', controller: 'DashboardCtrl' })

「apps.js」に新しいルートを追加します。

yo angular:service user

また、ユーザーがログインしているかどうかを追跡する必要があります。そのために別のサービスを作成しましょう。

// user.js angular.module('clientApp') .factory('userService', function() { var username = ''; return { username : username }; }); .success(function(data) { if(data.hasOwnProperty('success')) { userService.username = $scope.email; $location.path('/dashboard');; } });

また、サインアップコントローラーを変更して、ユーザーを登録したばかりのユーザーに設定します。

public static Result login() { Form loginForm = Form.form(Login.class).bindFromRequest(); if (loginForm.hasErrors()) { return badRequest(loginForm.errorsAsJson()); } Login loggingInUser = loginForm.get(); User user = User.findByEmailAndPassword(loggingInUser.email, loggingInUser.password); if(user == null) { return badRequest(buildJsonResponse('error', 'Incorrect email or password')); } else { session().clear(); session('username', loggingInUser.email); ObjectNode wrapper = Json.newObject(); ObjectNode msg = Json.newObject(); msg.put('message', 'Logged in successfully'); msg.put('user', loggingInUser.email); wrapper.put('success', msg); return ok(wrapper); } } public static Result logout() { session().clear(); return ok(buildJsonResponse('success', 'Logged out successfully')); } public static Result isAuthenticated() { if(session().get('username') == null) { return unauthorized(); } else { ObjectNode wrapper = Json.newObject(); ObjectNode msg = Json.newObject(); msg.put('message', 'User is logged in already'); msg.put('user', session().get('username')); wrapper.put('success', msg); return ok(wrapper); } } public static class Login extends UserForm { @Constraints.Required public String password; }

投稿を追加する主な機能を追加する前に、ログインとログアウトの機能、ダッシュボードへのユーザー情報の表示、バックエンドでの認証サポートの追加など、その他の重要な機能について説明します。

基本認証

Playアプリケーションにジャンプして、ログインアクションとログアウトアクションを実装しましょう。これらの行を「Application.java」に追加します。

public class Secured extends Security.Authenticator { @Override public String getUsername(Context ctx) { return ctx.session().get('username'); } @Override public Result onUnauthorized(Context ctx) { return unauthorized(); } }

次に、認証されたユーザーにのみ特定のバックエンド呼び出しを許可する機能を追加しましょう。次のコードで「Secured.java」を作成します。

yo angular:controller menu

このクラスは、後で新しいアクションを保護するために使用します。次に、AngularJSアプリケーションのメインメニューを微調整して、ユーザー名とログアウトのリンクを表示する必要があります。そのためには、コントローラーを作成する必要があります。

// menu.js angular.module('clientApp') .controller('MenuCtrl', function ($scope, $http, userService, $location) { $scope.user = userService; $scope.logout = function() { $http.get('/app/logout') .success(function(data) { if(data.hasOwnProperty('success')) { userService.username = ''; $location.path('/login'); } }); }; $scope.$watch('user.username', function (newVal) { if(newVal === '') { $scope.isLoggedIn = false; } else { $scope.username = newVal; $scope.isLoggedIn = true; } }); }); yo angular:controller login yo angular:view login

ログインページ用のビューとコントローラーも必要です。

Email Password Log in // login.js angular.module('clientApp') .controller('LoginCtrl', function ($scope, userService, $location, $log, $http, alertService) { $scope.isAuthenticated = function() { if(userService.username) { $log.debug(userService.username); $location.path('/dashboard'); } else { $http.get('/app/isauthenticated') .error(function() { $location.path('/login'); }) .success(function(data) { if(data.hasOwnProperty('success')) { userService.username = data.success.user; $location.path('/dashboard'); } }); } }; $scope.isAuthenticated(); $scope.login = function() { var payload = { email : this.email, password : this.password }; $http.post('/app/login', payload) .error(function(data, status){ if(status === 400) { angular.forEach(data, function(value, key) { if(key === 'email' || key === 'password') { alertService.add('danger', key + ' : ' + value); } else { alertService.add('danger', value.message); } }); } else if(status === 401) { alertService.add('danger', 'Invalid login or password!'); } else if(status === 500) { alertService.add('danger', 'Internal server error!'); } else { alertService.add('danger', data); } }) .success(function(data){ $log.debug(data); if(data.hasOwnProperty('success')) { userService.username = data.success.user; $location.path('/dashboard'); } }); }; });
  • Sign up!
  • Login
{{ username }} Toggle Dropdown
  • Dashboard
  • Logout

次に、メニューを微調整して、ユーザーデータを表示できるようにします。

yo angular:view addpost

これで、アプリケーションにログインすると、次の画面が表示されるはずです。

スクリーンショットを再生

投稿の追加

基本的なサインアップと認証のメカニズムが整ったので、投稿機能の実装に取り​​掛かることができます。投稿を追加するための新しいビューとコントローラーを追加しましょう。

Subject Post Submit post yo angular:controller addpost // addpost.js angular.module('clientApp') .controller('AddpostCtrl', function ($scope, $http, alertService, $location) { $scope.post = function() { var payload = { subject : $scope.subject, content: $scope.content }; $http.post('/app/post', payload) .error(function(data, status) { if(status === 400) { angular.forEach(data, function(value, key) { if(key === 'subject' || key === 'content') { alertService.add('danger', key + ' : ' + value); } else { alertService.add('danger', value.message); } }); } else if(status === 401) { $location.path('/login'); } else if(status === 500) { alertService.add('danger', 'Internal server error!'); } else { alertService.add('danger', data); } }) .success(function(data) { $scope.subject = ''; $scope.content = ''; alertService.add('success', data.success.message); }); }; }); .when('/addpost', { templateUrl: 'views/addpost.html', controller: 'AddpostCtrl' })

次に、「app.js」を更新して次のものを含めます。

  • Dashboard
  • Add post
  • Logout

次に、「index.html」を変更して、ダッシュボードメニューの「addpost」ビューへのリンクを追加します。

// Post.java public class Post extends Controller { public static Result addPost() { Form postForm = Form.form(PostForm.class).bindFromRequest(); if (postForm.hasErrors()) { return badRequest(postForm.errorsAsJson()); } else { BlogPost newBlogPost = new BlogPost(); newBlogPost.commentCount = 0L; newBlogPost.subject = postForm.get().subject; newBlogPost.content = postForm.get().content; newBlogPost.user = getUser(); newBlogPost.save(); } return ok(Application.buildJsonResponse('success', 'Post added successfully')); } private static User getUser() { return User.findByEmail(session().get('username')); } public static class PostForm { @Constraints.Required @Constraints.MaxLength(255) public String subject; @Constraints.Required public String content; } }

Playアプリケーション側で、addPostメソッドを使用して新しいコントローラーPostを作成しましょう。

POST /app/post controllers.Post.addPost

ルートファイルに新しいエントリを追加して、ルーティングで新しく追加されたメソッドを処理できるようにします。

// Application.java public static Result getPosts() { return ok(Json.toJson(BlogPost.find.findList())); }

この時点で、新しい投稿を追加できるはずです。

Playに新しい投稿を追加する

投稿の表示

投稿を表示できない場合、投稿を追加してもほとんど価値がありません。私たちがやりたいのは、メインページにすべての投稿をリストすることです。まず、アプリケーションコントローラーに新しいメソッドを追加します。

GET /app/posts controllers.Application.getPosts

そしてそれをルートファイルに登録します:

// main.js angular.module('clientApp') .controller('MainCtrl', function ($scope, $http) { $scope.getPosts = function() { $http.get('app/posts') .success(function(data) { $scope.posts = data; }); }; $scope.getPosts(); });

次に、AngularJSアプリケーションで、メインコントローラーを変更します。

{{ post.subject }}

{{ post.content }}

Post by: {{ post.user.email }} | Comments {{ post.commentCount }}

最後に、「main.html」からすべてを削除し、これを追加します。

yo angular:controller viewpost yo angular:view viewpost

これで、アプリケーションのホームページをロードすると、次のようなものが表示されるはずです。

AngularjsPlayのサンプルが読み込まれました

また、おそらく個々の投稿に対して個別のビューを用意する必要があります。

// viewpost.js angular.module('clientApp') .controller('ViewpostCtrl', function ($scope, $http, alertService, userService, $location) { $scope.user = userService; $scope.params = $routeParams; $scope.postId = $scope.params.postId; $scope.viewPost = function() { $http.get('/app/post/' + $scope.postId) .error(function(data) { alertService.add('danger', data.error.message); }) .success(function(data) { $scope.post = data; }); }; $scope.viewPost(); });

{{ post.subject }}

{{ post.content }}

Post by: {{ post.user.email }} | Comments {{ post.commentCount }}
app.js: .when('/viewpost/:postId', { templateUrl: 'views/viewpost.html', controller: 'ViewpostCtrl' })

そしてAngularJSルート:

// Application.java public static Result getPost(Long id) { BlogPost blogPost = BlogPost.findBlogPostById(id); if(blogPost == null) { return notFound(buildJsonResponse('error', 'Post not found')); } return ok(Json.toJson(blogPost)); }

以前と同様に、アプリケーションコントローラーに新しいメソッドを追加します。

GET /app/post/:id controllers.Application.getPost(id: Long)

…そして新しいルート:

// dashboard.js angular.module('clientApp') .controller('DashboardCtrl', function ($scope, $log, $http, alertService, $location) { $scope.loadPosts = function() { $http.get('/app/userposts') .error(function(data, status) { if(status === 401) { $location.path('/login'); } else { alertService.add('danger', data.error.message); } }) .success(function(data) { $scope.posts = data; }); }; $scope.loadPosts(); });

これで、http:// localhost:9000 /#/ viewpost / 1に移動すると、特定の投稿のビューをロードできるようになります。次に、ダッシュボードにユーザーの投稿を表示する機能を追加しましょう。

My Posts

No posts yet. Add a post {{ post.subject }} | Comments {{ post.commentCount }}
// Post.java public static Result getUserPosts() { User user = getUser(); if(user == null) { return badRequest(Application.buildJsonResponse('error', 'No such user')); } return ok(Json.toJson(BlogPost.findBlogPostsByUser(user))); }

また、Postコントローラーに新しいメソッドを追加し、その後にこのメソッドに対応するルートを追加します。

GET /app/userposts controllers.Post.getUserPosts // Post.java public static Result addComment() { Form commentForm = Form.form(CommentForm.class).bindFromRequest(); if (commentForm.hasErrors()) { return badRequest(commentForm.errorsAsJson()); } else { PostComment newComment = new PostComment(); BlogPost blogPost = BlogPost.findBlogPostById(commentForm.get().postId); blogPost.commentCount++; blogPost.save(); newComment.blogPost = blogPost; newComment.user = getUser(); newComment.content = commentForm.get().comment; newComment.save(); return ok(Application.buildJsonResponse('success', 'Comment added successfully')); } } public static class CommentForm { @Constraints.Required public Long postId; @Constraints.Required public String comment; }

これで、投稿を作成すると、ダッシュボードに一覧表示されます。

ダッシュボードにリストされた新しい投稿

コメント機能

コメント機能を実装するために、Postコントローラーに新しいメソッドを追加することから始めます。

POST /app/comment controllers.Post.addComment

そしていつものように、このメソッドの新しいルートを登録する必要があります。

$scope.addComment = function() { var payload = { postId: $scope.postId, comment: $scope.comment }; $http.post('/app/comment', payload) .error(function(data, status) { if(status === 400) { angular.forEach(data, function(value, key) { if(key === 'comment') { alertService.add('danger', key + ' : ' + value); } else { alertService.add('danger', value.message); } }); } else if(status === 401) { $location.path('/login'); } else if(status === 500) { alertService.add('danger', 'Internal server error!'); } else { alertService.add('danger', data); } }) .success(function(data) { alertService.add('success', data.success.message); $scope.comment = ''; $scope.viewPost(); }); };

AngularJSアプリケーションでは、「viewpost.js」に以下を追加します。

By: {{ comment.user.email }}
{{ comment.content }}

Login to comment

Add comment

Comment Add comment

そして最後に、「viewpost.html」に次の行を追加します。

|_+_|

これで、投稿を開くと、コメントを追加して表示できるようになります。

コメントのスクリーンショットを表示

次は何ですか?

このチュートリアルでは、RESTAPIバックエンドとして機能するPlayアプリケーションを使用してAngularJSブログを作成しました。アプリケーションには堅牢なデータ検証(特にクライアント側)とセキュリティが欠けていますが、これらのトピックはこのチュートリアルの範囲外でした。この種のアプリケーションを構築するための多くの可能な方法の1つを示すことを目的としていました。便宜上、このアプリケーションのソースコードはにアップロードされています GitHubリポジトリ 。

Webアプリケーション開発におけるAngularJSとPlayのこの組み合わせが興味深いと思われる場合は、次のトピックをさらに確認することを強くお勧めします。

  • AngularJSドキュメント
  • ドキュメントを再生する
  • Playをバックエンドとして使用する1ページのJSアプリで推奨されるセキュリティアプローチ (例を含む)
  • OAuthなしの安全なRESTAPI
  • ReadyPlay認証プラグイン (単一ページのJavaScriptアプリケーションには完全には使用できない場合がありますが、良い例として使用できます)

Brexitが金融サービスセクターに与える影響

財務プロセス

Brexitが金融サービスセクターに与える影響
グラス・スティーガル法:その廃止は金融危機を引き起こしたか?

グラス・スティーガル法:その廃止は金融危機を引き起こしたか?

投資家と資金調達

人気の投稿
AWSを使用した柔軟なA / Bテスト[メール保護]
AWSを使用した柔軟なA / Bテスト[メール保護]
なぜこれほど多くのPythonがあるのですか?
なぜこれほど多くのPythonがあるのですか?
Firebase認証を使用してロールベースのAPIを構築する方法
Firebase認証を使用してロールベースのAPIを構築する方法
適切に構造化されたロジック:GolangOOPチュートリアル
適切に構造化されたロジック:GolangOOPチュートリアル
ApeeScapeは、スタートアップ起業家に低コストでエリートプログラミングの才能を提供します
ApeeScapeは、スタートアップ起業家に低コストでエリートプログラミングの才能を提供します
 
スケッチとルーパーを使ってすぐに心を曲げるイラストを作成する
スケッチとルーパーを使ってすぐに心を曲げるイラストを作成する
ミニチュートリアル–Figmaボタンコンポーネントの操作
ミニチュートリアル–Figmaボタンコンポーネントの操作
Android開発者が犯す最も一般的な間違いトップ10:プログラミングチュートリアル
Android開発者が犯す最も一般的な間違いトップ10:プログラミングチュートリアル
最高のデータ視覚化ツールの完全な概要
最高のデータ視覚化ツールの完全な概要
将来のUIとデザインサンドボックスの終了
将来のUIとデザインサンドボックスの終了
人気の投稿
  • 諮問委員会の設置方法
  • ダイアグラムやチャートは、アイデアを生み出すための効果的なツールになり得ます。
  • ビットコインはどのアルゴリズムを使用しますか
  • SQLサーバーは、t-sqlまたはtransact-sqlと呼ばれるSQLの拡張バージョンを使用します。
  • 知覚組織のゲシュタルト法
  • 日常生活におけるゲシュタルトの例
  • 最近発生した可能性のある攻撃の原因を特定することに関心があります
カテゴリー
技術 デザイナーライフ Webフロントエンド モバイルデザイン ブランドデザイン バックエンド その他 革新 モバイル 分散チーム

© 2021 | 全著作権所有

apeescape2.com