NG-IFとNG-Show/Hideの違いは何ですか?
最初の違いは、NG-IFがDOMノードの後の式がtrueである場合にのみ作成され、最初にNG-Showが作成され、表示:ブロックと表示:ディスプレイを制御するために使用されないものはありません。
2番目の違いは、NG-IFが(暗黙的に)新しいスコープを生成することであり、Ng-Switch、Ng-Includeなどがインターフェイスを動的に作成するために同じことが当てはまることです。
これにより、NG-ModelがNG-IFの基本変数と結合し、このモデルを外側DIVの別のディスプレイ領域に結合します。内側の層が変化すると、すでに2つの変数があるため、外層は同期して変化しません。
<p> {{name}} </p> <div ng-if = "true"> <入力型= "text" ng-model = "name"> </div>NG-Showには、独自の第1レベルの範囲が付属していないため、この問題はありません。
この種の問題を回避する方法は、ベース変数(x)に直接バインドする代わりに、ページ内の要素をオブジェクトのプロパティ(data.x)に常にバインドすることです。
詳細については、Angularjsのスコープを参照してください
Ng-Repeatが配列を繰り返すと、配列に同じ値がある場合、どのような問題が発生し、それらを解決する方法は何ですか?
リピーターの複製は許可されていません。 $ indexのトラックを追加すると、それを解くことができます。もちろん、配列内の各アイテムを一意に識別できる限り(DOMとデータの間に関連性を作成する)、通常の値でトレースすることもできます。
ngクリックで書かれた式は、JSネイティブオブジェクトのメソッドを使用できますか?
NGクリックの式だけでなく、ネイティブJSメソッドのみがページにある限り、直接呼び出すことはできません。これらはページに対応するコントローラーの$スコープに存在しないためです。
栗を取る:
<p> {{parseint(55.66)}} <p>
何も表示されないことがわかります。
ただし、この関数を$ scopeで追加する場合:
$ scope.parseint = function(x){return parseint(x);}もちろん、このような問題はありません。
この種の要件については、フィルターを使用することが良い選択かもしれません。
<p> {{13.14 | parseintfilter}} </p> app.filter( 'parseintfilter'、function(){return function(item){return parseint(item);}}){{now | 'yyyy-mm-dd'}}この式では、垂直線とその後のパラメーターをどのようにカスタマイズできますか?
フィルター、フォーマットデータ、入力を受信し、特定のルールに従って処理し、処理結果を返します。
内蔵フィルター
ビルトインフィルターには9種類があります。
日付(日付)
通貨
Limitto(アレイまたは文字列の長さを制限)
Orderby(sort)
小文字(小文字)
大文字(キャップ)
番号(数字のフォーマット、1000のセパレーターを追加し、小数の場所の数を制限するパラメーターを受信します)
フィルター(配列を処理し、サブストリングを含む要素を除外)
JSON(JSONオブジェクトのフォーマット)
フィルターを使用するには2つの方法があります。1つはページ上に直接次のことです。
<p> {{now |日付: 'yyyy-mm-dd'}} </p>
もう1つはJSで使用することです。
// $フィルター( 'フィルター名')(フィルタリングする必要があるオブジェクト、パラメーター1、パラメーター2、...)
$ filter( 'date')(now、 'yyyy-mm-dd hh:mm:ss');
カスタムフィルター
// form app.filter( 'filter name'、function(){return function(フィルタリングする必要があるオブジェクト、フィルターパラメーター1、フィルターパラメーター2、...){// ...処理後にオブジェクトを返すために何かをします;}}); // chestnut app.filter( 'timesfilter'、function(){return function(item、times){var result = ''; for(var i = 0; i <times; i ++){result+= item;} return result;}}))工場、サービス、プロバイダーの関係は何ですか?
工場
サービス方法とデータをオブジェクトに入れて、このオブジェクトを返します
app.Factory( 'fooservice'、function(){return {target: 'factory'、sayhello:function(){return 'hello' + this.target;}}});サービス
コンストラクターメソッドを介してサービスを作成し、インスタンス化されたオブジェクトを返します
app.service( 'fooservice'、function(){var self = this; this.target = 'service'; this.sayhello = function(){return 'hello' + self.target;}});プロバイダー
configを介して構成できるサービスを作成します。 $ getで返されるのは、工場を使用してサービスのコンテンツを作成することです
app.provider( 'fooservice'、function(){this.configdata = 'init data'; this.setconfigdata = function(data){if(data){this.configdata = data;}} this。$ get = function(){var self()return {thish {target: 'provider:' provider: 'provider: ' + this.target;}}}}}基礎となる実装の観点から、サービスは工場に電話をかけ、そのインスタンスを返します。工場はプロバイダーに電話をかけ、$ getで定義されたコンテンツを返します。工場とサービスの機能は類似していますが、工場は何でも返すことができる通常の関数であることを除いて(返品にアクセスできるので、それらの私的変数の書き方、知っています)。サービスはコンストラクターであり、返品できません(これに縛られたものにアクセスできます)。プロバイダーは、構成可能な工場を返す拡張工場です。
Angularjs Factory vs Service vs Providerを参照してください
Angularのデータ結合に使用されるメカニズムは何ですか?原則の詳細な説明
汚い検査メカニズム。
双方向データ結合は、Angularjsのコアメカニズムの1つです。ビューにデータの変更がある場合、モデルに更新されます。モデルにデータの変更がある場合、ビューも同時に更新されます。明らかに、これには監視が必要です。
原則は、AngularがScopeモデルにリスニングキューをセットアップして、データの変更と更新ビューをリッスンすることです。オブジェクトがビューにバインドされるたびに、Angularjsは$ watchキューに$ watchを挿入して、モニターモニターに変更があるかどうかを検出します。ブラウザがAngularコンテキストで処理できるイベントを受信すると、$ DIGESTループがトリガーされ、すべての$ Watchを横断し、最終的にDOMを更新します。
栗を与えます
<button ng-click = "val = val+1"> 1 </button>を増やします
クリックすると、更新操作が生成されます(少なくとも2つの$ダイジェストループがトリガーされます)
ボタンを押します
ブラウザはイベントを受信し、角度コンテキストに入ります
$ digestループが実行され始め、各$監視が変更されるかどうかを照会します
$監視$ scope.valが報告された変更を監視するため、$ digestループが強制されます
New $ Digestループで変更は検出されません
ブラウザはコントローラーを取り戻し、$ scope.valの新しい値に対応するDOMを更新します
$ digestループの上限は10倍です(無限のループを防ぐために、10回以上例外がスローされます)。
AngularJSのデータバインディングを参照してください
2つの水平インターフェイスはAとbをブロックします。イベントがAでトリガーされている場合、Bはどのような方法を知ることができますか?原則の詳細な説明
言い換えれば、この問題は、水平インターフェイスモジュール間で通信する方法です。 2つの方法があります。1つはサービスを共有することで、もう1つはイベントに基づいています。
共有サービス
Angularでは、Singletonオブジェクトを工場で生成でき、このオブジェクトは通信を必要とするモジュールAおよびBに注入できます。
イベントに基づいています
これを行うには2つの方法があります
1つ目は、親コントローラーを使用することです。チャイルドコントローラーで、親コントローラーにイベント($ emit)をトリガーし、親コントローラーの($ on)イベントを聞いてから、子コントローラーにブロードキャスト($ broadcast)を行います。このようにして、イベントによって運ばれるパラメーターを通じて、データは親コントローラーと同じレベルのコントローラーを介して伝播されます。
2番目のタイプは、$ Rootscopeを使用することです。各Angularアプリケーションには、デフォルトでルートスコープ$ Rootscopeがあります。ルートスコープは最上位にあり、そこからぶら下がっているすべてのレベルでスコープがあります。したがって、SubControllerが$ Rootscopeを使用してブロードキャストと受信イベントを直接使用する場合、ピア間の通信を達成できます。
AngularJSのコントローラー間の通信を参照してください
角度アプリケーションはどのように十分に階層化されるべきですか?
ディレクトリ構造を分割します
小さなプロジェクトの場合、次のようなファイルタイプでそれらを整理できます。
CSSJSコントローラーモデルサービスフィルター
ただし、大規模なプロジェクトでは、次のようなビジネスモジュールに従って分割することをお勧めします。
CSSMODULESアカウントコントローラーモデルサービスフィルターテンプレートディスクコントローラーモデルサービスフィルターテンプレート
公共のものを保存するために、モジュールの下に共通のディレクトリを持つことが最善です。
論理コードの分割
MVVMフレームワークとして、角度アプリケーションは、モデル、ビューモデル(コントローラー)、およびビューに従って分割する必要があります。
ここでのロジックコードの分割は、主にコントローラー層を可能な限り非常に薄くしようとすることを指します。共有ロジックをサービスに抽出し(バックグラウンドデータリクエスト、データ共有とキャッシュ、イベントベースのモジュール間通信など)、共有インターフェイス操作をディレクティブに抽出し(日付選択、ページングなどをカプセル化するなど)、共有形式の操作をフィルターなどに抽出します。
複雑なアプリケーションでは、ハードディスク(ディスク)モジュールなどのエンティティに対応するコンストラクターを確立することもできます。これには、リスト、新しい作成、詳細、対応するコントローラーなどのいくつかのビューがあります。次に、データの追加、削除、修正、検証操作を完了するために、ディスクコンストラクターを構築できます。ディスク関連のコントローラーがある場合、ディスクコンストラクターがディスクコンストラクターに注入され、インスタンスが生成されます。このインスタンスには、追加、削除、変更、および検証の方法があります。これには、明確なレイヤーだけでなく、再利用も実現します(コントローラー層を薄くする)。
サンニングクラウドセンターのAngularjsの詳細な練習を参照してください
角度アプリケーションに一般的に使用されるルーティングライブラリとその違いは何ですか?
ngrouteおよびui.routerは一般的にAngular1.xで使用されており、Angular2向けに設計された新しいルーター(コンポーネント指向)もあります。背後にあるものは実際のプロジェクトでは使用されていないので、私はそれについて話しません。
ngrouteまたはui.routerであろうと、フレームワークの追加機能として、モジュール依存関係の形で導入する必要があります。
違い
ngrouteモジュールは角度ルーティングモジュールであり、UI.RouterモジュールはNgrouteモジュールに基づいて開発されたサードパーティモジュールです。
UI.Routerは状態(状態)に基づいており、ngrouteはURLに基づいており、UI.Routerモジュールにはより強力な機能があり、主にビューのネスティングの側面に反映されています。
UI.Routerを使用して、明確な親子関係を持つルートを定義し、UI-Viewディレクティブを介して親ルーティングテンプレートの<Div UI-View> </div>にチャイルドルーティングテンプレートを挿入し、それによってネストの表示を実現します。これはngrouteで定義することはできません。 <div ng-view> </div>が親子ビューで同時に使用されている場合、デッドループに分類されます。
例
ngroute
var app = angular.module( 'ngrouteapp'、['ngroute']); app.config(function($ routeprovider){$ routeprovider .when( '/main'、{templateurl: "main.html"、コントローラー: 'mainctrl'})。ui.router
var app = angular.module( "uirouteapp"、["ui.router"])コントローラー: 'mainctrl'})
Angular Directiveを使用して完全なコンポーネントシステムを計画している場合、どのような課題に遭遇する可能性がありますか?
私は自分で指令を備えた完全なコンポーネントのセットを作成したことがないので、説明することはできません。
考えることができることの1つは、コンポーネントが外部の世界とどのように相互作用するか、そしてそれらを単純な構成でどのように使用できるかです。
さまざまなチームによって開発された角度アプリケーション。それらを統合したい場合、どのような問題が発生する可能性があり、それらを解決する方法は何ですか?
異なるモジュール間の競合に遭遇する可能性があります。
たとえば、1つのチームのすべての開発はModuleaの下で実行されますが、別のチームによって開発されたコードはModuleBの下で実行されます
angular.module( 'myapp.modulea'、[]).factory( 'servicea'、function(){...})angular.module( 'myapp.moduleb'、[])。これにより、2つのモジュールの下でServiceaが上書きされます。
Angular1.xには良い解決策はないように思われるため、初期段階で統一された計画を立て、合意を作り、契約に従って厳密に発展することが最善です。各開発者は特定のブロックコードのみを書き込みます。
Angularの欠点は何ですか?
強い制約
これにより、学習コストが高くなり、フロントエンドには友好的ではありません。
しかし、Angularjsの規則に従うと、生産性は高く、Javaプログラマーに優しいものになります。
SEOを助長しません
すべてのコンテンツが動的に取得およびレンダリングされるため、検索エンジンはクロールできません。
ソリューションの1つは、通常のユーザーアクセスのために、サーバーがAngularJSアプリケーションのコンテンツに応答することです。検索エンジンアクセスの場合、SEO専用にHTMLページに応答します。
パフォーマンスの問題
MVVMフレームワークとして、データの双方向のバインディングが実装されるため、大きな配列と複雑なオブジェクトにパフォーマンスの問題が発生します。
角度アプリケーションのパフォーマンスを最適化するために使用できる方法:
監視項目を削減します(変更されないデータの一方向バインディングなど)
インデックスを積極的に設定します(トラックを指定します。単純なタイプはデフォルトでインデックスとして自分自身を使用し、オブジェクトはデフォルトで$$ハッシュキーを使用します。
レンダリングされたデータの量(ページング、毎回データの一部を取得するなど、必要に応じて取得)を減らします)
データの平坦化(たとえば、ツリー構造の場合、平らな構造を使用してマップとツリーのデータを構築します。ツリーで動作する場合、フラットデータと同じ参照であるため、ツリーデータの変更は元のフラットデータに同期されます)
さらに、Angular1.xの場合、汚れたチェックとモジュールのメカニズムに問題があります。
携帯
イオンは試してみることができますが、完璧ではありません。
2015年1月のAngularに関するPeter-Paul Kochの見解を表示する方法は?
コントローラーは、Angular 1.2で導入された構文とどのように見ていますか?
最も基本的な利点
Angular 1.2の前に、ビューのバインディングは$スコープに直接結合していました
関数myctrl($ scope){$ scope.a = 'aaa'; $ scope.foo = function(){...}}Controllerasを使用すると、$スコープを再度注入する必要はありませんが、コントローラーは非常にシンプルなJavaScriptオブジェクト(POJO)、より純粋なViewModelになります。
function myctrl(){// VMを使用してこれをキャプチャして、このvar vm = thisを使用するとコンテキストが変更される内部関数を回避します。 vm.a = 'aaa';}原理
ソースコードの実装の観点から、Controlleras構文は、たとえばコントローラーオブジェクトのASエイリアスとの$スコープに属性を作成するだけです。
if(directive.controlleras){locals。$ scope [directive.controlleras] = controllerInstance;}ただし、上記のコントローラーをより多くのPOJOにすることに加えて、AngularJSスコープに関連するピットに遭遇することも避けることもできます(つまり、NG-IFが第1レベルのスコープを生成するピットです。
<div ng-controller = "testctrl as vm"> <p> {{name}} </p> <div ng-if = "vm.name"> <入力タイプ= "テキスト" ng-model = "vm.name"> </div> </div>質問
Controllerasで遭遇する問題の1つは、$スコープが注入されないため、$ emit、$ broadcast、$ on、$ watchなどのメソッドを使用できないことです。これらのイベント関連操作は、カプセル化および均一に処理することができます。または、$スコープが特別な治療のために単一のコントローラーに導入されます。
構文とスコープとしての角度コントローラーを参照します
Angularの「依存関係注射」の詳細
栗
依存関係注射は、コード間の依存関係を処理し、コンポーネント間の結合を削減することを目的とするソフトウェア設計パターンです。
たとえば、AngularJを使用していない場合は、バックグラウンドからデータをクエリし、フロントエンドに表示する場合は、これを行う必要があります。
var Animalbox = document.queryselector( '。動物箱'); var httprequest = {get:function(url、callback){console.log(url + 'requested'); var動物= ['cat'、 'dog'、 'rabbit'];コールバック(動物); }} var render = function(el、http){http.get( '/api/動物'、function(動物){el.innerhtml = animals;})} render(httprequest、animalbox);ただし、レンダリングが呼び出されたときにパラメーターが渡されない場合、次のように、ELとHTTPが見つからないためエラーが報告されます(依存関係が定義され、依存関係は実行時に自動的に見つかりません)
与える();
// typeRror:未定義のプロパティ「取得」を読み取ることができません
そして、Angularjsを使用して、これを直接行うことができます
関数myctrl =($ scope、$ http){$ http.get( '/api/animals')。成功(function(data){$ scope.animals = data;})}言い換えれば、Angular Appが実行されている場合、myctrlが呼び出され、2つの依存関係、$スコープ、$ httpが自動的に注入されます。
原理
AngularJSは、コンストラクターのパラメーター名を介して依存関係サービス名を誘導し、toString()を使用してこの定義された関数に対応する対応する文字列を見つけ、次に定期的にパラメーター(依存関係)を解析し、依存関係マップで対応する依存関係を取得し、それをインスタンスします。
それを単純化するために、それはおそらくこのようなものです:
var inject = {//ストレージ依存関係マッピング関係ストレージ:{}、//依存関係レジスタ:function(name、resource){this.storage [name] = resource; }、//依存関係を解析し、call resolve:function(target){var self = this; var fn_args =/^function/s*[^/(]*/(/s*([^//)]*)/m; var strip_comments = /((///./.*$ )|(////s/s ]*?/*//////////mg; fntext = target.toString()。置換(sprip_comments、 ''); argdecl = fntext.match(fn_args)[1] .split(/、?/g); var args = []; argdecl.foreach(function(arg){if(self.storage [arg]){args.push(self.storage [arg]);}})return function(){target.apply({}、args); }}}このインジェクターを使用して、AngularJを使用しない以前の栗を変更した後に呼び出すことができます。
inject.register( 'el'、animalbox); inject.register( 'ajax'、httprequest); reender = inject.resolve(render); rewend();
質問
AngularJSインジェクターは、関数のパラメーター名が依存関係の名前であると想定しているため、コードが圧縮された後(パラメーターが名前が変更された)後、依存関係が前の栗のように注入された場合、依存関係を検索します。依存関係は見つかりません。
//関数myctrl =($ scope、$ http){...} //関数myctrl =(a、b){...}したがって、通常、依存関係を注入するために次の2つの方法が使用されます(依存関係が追加される順序には要件があります)。
配列アノテーション方法
myapp.controller( 'myctrl'、['$ scope'、 '$ http'、function($ scope、$ http){...}))明示的な$注入
myapp.controller( 'myctrl'、myctrl); function myctrl =($ scope、$ http){...} myctrl。$ inject = ['$ scope'、 '$ http'];補充します
DIコンテナの場合、依存関係の登録、依存関係の宣言、およびオブジェクトの取得の3つの要素を含める必要があります。
AngularJSでは、モジュールと$の両方の提供が依存関係の登録を提供できます。内蔵インジェクターはオブジェクトを取得できます(自動的に依存関係の噴射を完全に完了します)。依存関係の宣言は、前の質問に記載されているとおりです。
これが栗です
//モジュールの場合、複数のパラメーターが渡されます。つまり、新しいモジュールが作成され、空の配列は他のモジュールに依存しないことを意味します//モジュール(モジュール名)のみがあります。 Angular.module( 'myapp.services'、[])// $プロバイダーには工場、サービス、プロバイダー、値、定数// httpserviceangular.module( 'myapp.services')。
参照してください
[Angularjs]自分で単純な依存噴射を実装します
角度のモジュールとインジェクター、つまり依存関係噴射を理解します
AngularJSの依存噴射実用的なアプリケーションシナリオ
Angular2の表示方法
Angular1.xと比較して、Angular2は大きな変化をもたらし、ほぼ新しいフレームワークです。
TypeScript(TypeScriptを使用して開発できます)に基づいて、大規模なプロジェクトチームがコラボレーションする場合、強力な言語タイプがより有益です。
コンポーネント化により、開発とメンテナンスの効率が向上します。
動的荷重、新しいルーター、約束のネイティブサポートなどをサポートするモジュールもあります。
それは将来の基準に応え、他のフレームワークの利点を吸収しますが、これは楽しみにしていますが、学習することももっとあります(es、ts、rxなど)。
上記は、Angularjsインタビューの質問の情報を編集しています。今後も関連情報を追加し続けます。このウェブサイトへのご支援ありがとうございます!