ホームページ ウェブフロントエンド jsチュートリアル Angular.jsで開発する場合の注意点

Angular.jsで開発する場合の注意点

Dec 09, 2016 pm 04:07 PM
angular.js

前書き

私は最近 Angularjs を使っています。Knockout と比較すると、Angularjs の MVVM フレームワークはより強力で複雑です。しかし、実際にプロジェクトで使用すると、さまざまなチュートリアルがインターネット上に溢れています。 、さまざまな落とし穴に遭遇します。

1. ng-repeat

ng-repeatは、要素を繰り返し出力する必要があることを識別するために使用され、繰り返し出力される内容は一意である必要があります

<div ng-app="app" ng-controller="control">
  <h3 ng-repeat="content in repeatContent">ng-repeat: {{ content }}</h3>
</div>
ログイン後にコピー

let app = angular.module("app", []);
app.controller("control", ($scope) => {
  // 输出李滨泓
  $scope.repeatContent = ["李", "滨", "泓"];
  // 下面存在两个“泓”,会报错
  // $scope.repeatContent = ["李", "滨", "泓", "泓"];
})
ログイン後にコピー

2. プロバイダ間、サービス、ファクトリー

ファクトリー

ファクトリーの関係はサービスと非常に似ています。違いは、サービスを使用する必要がある場合、サービスを作成するために new キーワードを使用することです。 1 つだけ)サービス。 Factory は、必要なときに、関数関数のコレクション オブジェクトを返すなど、さまざまな形式のデータを返すメソッドです。

定義:

let app = angular.module("app", []);
 
// 这里可以注入 $http 等 Provider
app.factory("Today", () => {
  let date = new Date();
  return {
    year: date.getFullYear(),
    month: date.getMonth() + 1,
    day: date.getDate()
  };
});
ログイン後にコピー

使用インジェクション:

service

service は、使用時にはシングルトン オブジェクトであり、その特性により、何も返さないことができます。 new キーワードを使用して作成されますが、コントローラー間の通信やデータ対話にも使用できます。これは、コントローラーのスコープ チェーンが役に立たない場合 (たとえば、ルートを使用して別のページにジャンプし、別のページを使用して) 破棄されるためです。コントローラー)

定義:

app.controller("control", (Today) => {
  console.log(Today.year);
  console.log(Today.month);
  console.log(Today.day);
});
ログイン後にコピー
ログイン後にコピー

使用インジェクション:

let app = angular.module("app", []);
 
// 这里可以注入 $http 等 Provider
// 注意这里不可以使用 arrow function
// arrow function 不能作为 constructor
app.service("Today", function() {
  let date = new Date();
  this.year = date.getFullYear();
  this.month = date.getMonth() + 1;
  this.day = date.getDate();
});
ログイン後にコピー

プロバイダー

プロバイダーはサービスの構成可能なバージョンであると理解できます。プロバイダを提供する前に、プロバイダのいくつかのパラメータを設定します。

定義:

app.controller("control", (Today) => {
  console.log(Today.year);
  console.log(Today.month);
  console.log(Today.day);
});
ログイン後にコピー
ログイン後にコピー

インジェクションの使用:

let app = angular.module("app", []);
 
// 这里可以注入 $http 等 Provider
// 注意这里不可以使用 arrow function
// arrow function 不能作为 constructor
app.provider("Today", function() {
  this.date = new Date();
  let self = this;
 
  this.setDate = (year, month, day) => {
    this.date = new Date(year, month - 1, day);
  }
 
  this.$get = () => {
    return {
      year: this.date.getFullYear(),
      month: this.date.getMonth() + 1,
      day: this.date.getDate()
    };
  };
});
ログイン後にコピー

3. ハンドルバーが角度シンボル解決と競合する


シナリオ:

サーバーとしてnode.jsを使用する場合、中古ハンドルバーはnode.js が応答して URL をレンダリングするとき、そのテンプレートは変数解析シンボルとして { {} } を使用します。同様に、angular も変数解決シンボルとして { {} } を使用するため、node.js がページをレンダリングするときに、{ {} } 内の変数が存在しない場合はその領域がクリアされ、本来の意図はこれです。同時に、ハンドルバーの代わりに angular の解析にも使用したいので、現時点では angular のデフォルトの { {} } 解析シンボルを再定義する必要があります。つまり、次の例に示すように、依存関係の注入 $interpolateProvider を使用して定義します。

// 这里重新配置了今天的日期是 2015年2月15日
// 注意这里注入的是 TodayProvider,使用驼峰命名来注入正确的需要配置的 provider
app.config((TodayProvider) => {
  TodayProvider.setDate(2015, 2, 15);
});
 
app.controller("control", (Today) => {
  console.log(Today.year);
  console.log(Today.month);
  console.log(Today.day);
});
ログイン後にコピー

IV. ng-annotate-loader


ng-annotate-loader は、次の開発シナリオに適用されます。 webpack + angular であり、進行中の angular の問題を解決するために使用されます。 JS 圧縮後の依存関係注入の失敗とエラーの解決策

インストール

app.config($interpolateProvider => {
  $interpolateProvider.startSymbol(&#39;{[{&#39;);
  $interpolateProvider.endSymbol(&#39;}]}&#39;);
});
ログイン後にコピー

設定

$ npm install ng-annotate-loader --save-dev
ログイン後にコピー

5. 双方向データバインディング


Angular によって提供されていないイベントを使用する場合、 $scope のデータ変更によって $digest のダーティ チェック サイクルが発生しません。これにより、現時点では、モデルが変更されたときにビューが同期的に更新されなくなります。 、更新を自分で積極的にトリガーする必要があります

HTML

// webpack.config.js
{
  test: /\.js?$/,
  exclude: /(node_modules|bower_components)/,
  loader: &#39;ng-annotate!babel?presets=es2015&#39;
},
ログイン後にコピー

JavaScript

<div>{{ foo }}</div>
<button id="addBtn">go</button>
ログイン後にコピー

明らかに、この例の意図は、ボタンがクリックされると foo が成長してビューを更新することです。ただし、実際には、$scope.foo は変更されますが、ビューは更新されません。これは、foo には変更を検出した後に $apply を実行するための $watch がなく、最終的に $digest が発生するためです。そのため、自分で $apply をトリガーするか、$apply をトリガーする必要があります。データ変更をトリガーまたは検出するための $watch を作成します

JavaScript ($apply を使用)

app.controller("control", ($scope) => {
  $scope.foo = 0;
  document.getElementById("addBtn").addEventListener("click", () => {
    $scope.foo++;
  }, false);
})
ログイン後にコピー

JavaScript ($watch と $digest を使用)

app.controller("control", ($scope) => {
  $scope.foo = 0;
  document.getElementById("addBtn").addEventListener("click", () => {
     
    $scope.$apply(function() {
      $scope.foo++;
    });
 
  }, false);
})
ログイン後にコピー

6. $watch(watchExpression,listener, [objectEquality])

リスナーのコールバック関数を登録し、watchExpressionの値が変わるたびに

watchExpressionを呼び出す $digestが実行されるたびに呼び出され、検出対象の値を返す(同じ値が複数回入力された場合、watchExpressionは自身の値を変更しないでください。そうしないと、複数の $digest ループが発生する可能性があります。watchExpression は累乗する必要があるなど) 現在の watchExpression の戻り値が最後の watchExpression の戻り値と一致しない場合、


listener が呼び出されます (厳密に一致するには !== を使用します) objectEquality == true を除き、== の代わりに不整合を判断します)


objectEquality が true の場合、一貫性を決定するために angular.equals が使用され、これを保存するために angular.copy が使用されます。次の比較のためにオブジェクトをコピーします。これは、複雑なオブジェクトの検出が行われることを意味します。パフォーマンスとメモリの問題が発生します


7. $apply([exp])

$apply は、$scope の関数であり、$digest をトリガーするために使用されます。ループ

$apply疑似コード

app.controller("control", ($scope) => {
  $scope.foo = 0;
  $scope.flag = 0;
 
  $scope.$watch("flag", (newValue, oldValue) => {
 
    // 当 $digest 循环检测 flag 时,如果新旧值不一致将调用该函数
    $scope.foo = $scope.flag;
  });
 
  document.getElementById("addBtn").addEventListener("click", () => {
     
    $scope.flag++;
    // 主动触发 $digest 循环
    $scope.$digest();
  }, false);
})
ログイン後にコピー

$eval(expr)を使ってexpr式を実行


実行中に例外が発生した場合は$ExceptionHandler(e)を実行

最終的には、結果に関係なく、$digestループが1回実行されます


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Angular の学習ではスタンドアロン コンポーネントについて説明します (Standalone Component) Angular の学習ではスタンドアロン コンポーネントについて説明します (Standalone Component) Dec 19, 2022 pm 07:24 PM

この記事では、Angular の学習を継続し、Angular のスタンドアロン コンポーネント (Standalone Component) について簡単に理解できるようにします。

Angular Learning State Manager NgRx の詳細な説明 Angular Learning State Manager NgRx の詳細な説明 May 25, 2022 am 11:01 AM

この記事では、Angular のステートマネージャー NgRx について深く理解し、NgRx の使用方法を紹介します。

プロジェクトが大きすぎる場合はどうすればよいですか? Angular プロジェクトを合理的に分割するにはどうすればよいでしょうか? プロジェクトが大きすぎる場合はどうすればよいですか? Angular プロジェクトを合理的に分割するにはどうすればよいでしょうか? Jul 26, 2022 pm 07:18 PM

Angular プロジェクトが大きすぎます。適切に分割するにはどうすればよいですか?次の記事では、Angular プロジェクトを合理的に分割する方法を紹介します。

angular-datetime-picker 形式をカスタマイズする方法について話しましょう angular-datetime-picker 形式をカスタマイズする方法について話しましょう Sep 08, 2022 pm 08:29 PM

angular-datetime-picker 形式をカスタマイズするにはどうすればよいですか?次の記事ではフォーマットのカスタマイズ方法について説明していますので、皆様のお役に立てれば幸いです。

Angular の独立したコンポーネントの簡単な分析とその使用方法を説明します。 Angular の独立したコンポーネントの簡単な分析とその使用方法を説明します。 Jun 23, 2022 pm 03:49 PM

この記事では、Angular の独立コンポーネント、Angular で独立コンポーネントを作成する方法、および既存のモジュールを独立コンポーネントにインポートする方法について説明します。

Angular での依存関係の挿入を理解するためのステップバイステップ ガイド Angular での依存関係の挿入を理解するためのステップバイステップ ガイド Dec 02, 2022 pm 09:14 PM

この記事では、依存性注入について説明し、依存性注入によって解決される問題とそのネイティブの記述方法を紹介し、Angular の依存性注入フレームワークについて説明します。

Angular の :host、:host-context、::ng-deep セレクター Angular の :host、:host-context、::ng-deep セレクター May 31, 2022 am 11:08 AM

この記事では、Angular のいくつかの特別なセレクター (host、:host-context、::ng-deep) について詳しく説明します。お役に立てば幸いです。

Angular の @Component デコレータについての深い理解 Angular の @Component デコレータについての深い理解 May 27, 2022 pm 08:13 PM

コンポーネントはディレクティブのサブクラスであり、クラスを Angular コンポーネントとしてマークするために使用されるデコレーターです。次の記事では、Angular の @Component デコレータについて詳しく説明します。

See all articles