AnglarJSを使ってアプリケーションを構築する際に発生した問題と解決策(バージョンは1.3.9)
6248 ワード
最近会社でAnglarJS(1.3.9)を使って一つのプロジェクトを完成しました.ここで問題と解決策を記録します.
問題およびシーン:バックエンドは、要求中の
理由:
解決策:
問題とシーン:anglarで
理由:両者のpostはheaderに対して処理が異なり、jQueryはJSONの対象となるmyDataをプログレッシブ化しています.
解決策:Anglarの
問題およびシーン:scope上のmodelデータを更新するとき、
原因:このエラーの原因は、プロセス中に
ソリューション:この方法を呼び出した時にセキュリティチェックができます.パッケージコードは以下の通りです.
統一ブロックを追加してajaxに対する要求またはリターン処理を行います.
問題とシーン:私が遭遇したシーンは非同期要求を送信する時、バックエンドは先にユーザがログインしたかどうかを判断します.登録していない場合は
解決策:Anglarの中の
問題およびシーン:2つのビューがそれぞれ2つの
解決策:総じて言えば、Anglarにおけるコントローラ通信には3つの処理方法があります.は、スコープ継承方式、すなわち、親コントローラの内容をサブコントローラで継承する. は、イベントに基づく方法、すなわち サービス方式は、サービスの一例を書き込み、注入によって使用される. 最後の方法を選択しました.コード例は以下の通りです.
おわりに
以上は私のためにアングラーの応用を編纂する時出会った問題と解決案で、記録して共有してきました.皆さんのご指摘を歓迎します.
$http
サービスを使用してajax要求を送信した場合、バックエンドは判断できない.要求はXMLHttpRequest
である.問題およびシーン:バックエンドは、要求中の
header
のX-Requested-With
フィールドを読み取って、フロントエンドの要求が非同期要求XMLHttpRequest
であるかどうかを判断し、$http
サービスを使用して要求を送信した場合、バックエンドはfalse
と判断することがある.理由:
'X-Requested-With' : 'XMLHttpRequest'
は標準のheader
コンテンツではないので、Anglarはheader
においてデフォルトでこのフィールドを設定しない.解決策:
$httpProvider
に手動でフィールドを設定します.コードは以下の通りです. $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
ノート:公共サービスを作成することができます.この変更を配置方法で行うと、各moduleに公共サービスが注入されます.$http.post()
メソッドを使用するとパラメータのタイプが正しくありません.問題とシーン:anglarで
$http.post()
方法でデータを提出すると、バンドパラメータはForm Data
ではなく、JSONオブジェクトであることが分かり、サーバーが一般的な方法でパラメータを正確に取得できなくなり、jQueryの$.post()
方法を使って正しく取得することができます.理由:両者のpostはheaderに対して処理が異なり、jQueryはJSONの対象となるmyDataをプログレッシブ化しています.
var myData = { a : 1, b : 2 };
// jQuery post myData :"a=1&b=2"
angglarは明らかにこの処理をしていません.解決策:Anglarの
$httpProvider
のデフォルトの処理を修正します.コードは以下の通りです. $httpProvider.defaults.transformRequest = function(obj){
var str = [];
for(var p in obj) {
str.push(encodeURIComponent(p) + '=' + encodeURIComponent(obj[p]));
}
return str.join("&");
};
$httpProvider.defaults.headers.post = {
'Content-Type': 'application/x-www-form-urlencoded'
};
ノート:同じように公衆サービスでこの修正をすべきです.$scope.$apply(fn)
を呼び出して、表示時報エラーを更新します.問題およびシーン:scope上のmodelデータを更新するとき、
$rootScope:inprog
で傍受した場合、ビューは自動的に更新されていないことが分かり、手動でdigest
を呼び出してビューの更新を通知するが、エラーが発生することがある.原因:このエラーの原因は、プロセス中に
$scope.$apply(fn)
が実行中であり、これに基づいてこの方法を繰り返し起動することができないからです.ソリューション:この方法を呼び出した時にセキュリティチェックができます.パッケージコードは以下の通りです.
$scope.safeApply = function(fn) {
var phase = this.$root.$$phase;
if (phase === '$apply' || phase === '$digest') {
if (fn && (typeof(fn) === 'function')) {
fn();
}
} else {
this.$apply(fn);
}
};
ノート:$rootScope:inprog
変数は$scope.$apply(fn)
の内部属性であり、$$phase
またはscope
であれば、プロセス中にnull
の方法が実行されていないということを示しています.そうでなければ直接に起動できます.統一ブロックを追加してajaxに対する要求またはリターン処理を行います.
問題とシーン:私が遭遇したシーンは非同期要求を送信する時、バックエンドは先にユーザがログインしたかどうかを判断します.登録していない場合は
undefined
の$apply
にresponse
フィールドを追加します.フロントエンドはこのフィールドコントロールページを読み取り、このurlにジャンプします.私が最初に思い付いた解決策はフロントエンドが同じブロックを作る必要があります.非同期要求のすべてのheader
をブロックする.解決策:Anglarの中の
redirecturl
部分のソースコードの注釈を見て、ブロックの書き方をいくつか発見しました.私が選んだのは下記の通りです. * // register the interceptor as a service
* $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
* return {
* // optional method
* 'request': function(config) {
* // do something on success
* return config;
* },
*
* // optional method
* 'requestError': function(rejection) {
* // do something on error
* if (canRecover(rejection)) {
* return responseOrNewPromise
* }
* return $q.reject(rejection);
* },
* // optional method
* 'response': function(response) {
* // do something on success
* return response;
* },
*
* // optional method
* 'responseError': function(rejection) {
* // do something on error
* if (canRecover(rejection)) {
* return responseOrNewPromise
* }
* return $q.reject(rejection);
* }
* };
* });
* $httpProvider.interceptors.push('myHttpInterceptor');
response
をブロックしたコードは以下の通りです. commonService.factory('redirectInterceptor', function(){
return {
'response': function(response) {
if(response.headers().redirecturl) {
window.location.href = response.headers().redirecturl;
}
return response;
}
};
});
$httpProvider.interceptors.push('redirectInterceptor');
ノート:最後の行は、$httpProvider
のブロックにブロックを登録することを示し、同様に、パブリックサービスの構成方法に記載すべきである.response
間の通信問題問題およびシーン:2つのビューがそれぞれ2つの
$httpProvider
によって制御されている場合、そのうちの1つのビューが変化していることを、他のビューに通知する必要があります.解決策:総じて言えば、Anglarにおけるコントローラ通信には3つの処理方法があります.
controller
、controller
、$on
の3つの方法である. //JS
var app = angular.module('myApp', []);
app.factory('instance', function(){
return {};
});
app.controller('MainCtrl', function($scope, instance) {
$scope.change = function() {
instance.name = $scope.test;
};
});
app.controller('sideCtrl', function($scope, instance) {
$scope.add = function() {
$scope.name = instance.name;
};
});
//html
click me
my name
note:Anglarでのサービスは一例ですので、サービスでオブジェクトを生成し、このオブジェクトは依存注入によってすべてのコントローラで共有できます.クリックによって変化が生じない場合は、$emit
方法と併せて通信することもできる.他の2つの方法は駅構内記事を参照することができます.アングラーJSコントローラコントローラコントローラコントローラコントローラコントローラコントローラコントローラコントローラコントローラはどうやって通信しますか?おわりに
以上は私のためにアングラーの応用を編纂する時出会った問題と解決案で、記録して共有してきました.皆さんのご指摘を歓迎します.