Heim  >  Artikel  >  Web-Frontend  >  Was Sie bei der Entwicklung mit Angular.js beachten sollten

Was Sie bei der Entwicklung mit Angular.js beachten sollten

高洛峰
高洛峰Original
2016-12-09 16:07:16981Durchsuche

Vorwort

Ich habe in letzter Zeit mit Angularjs gespielt. Ich muss sagen, dass das MVVM-Framework von Angularjs überall im Internet verfügbar ist die tatsächlich in Projekten verwendet werden Sie werden von Zeit zu Zeit auf verschiedene Fallstricke stoßen.

1. ng-repeat

ng-repeat wird verwendet, um zu identifizieren, dass ein Element wiederholt ausgegeben werden muss und der Inhalt der wiederholten Ausgabe eindeutig sein muss

<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. Die Beziehung zwischen Anbieter, Service, Fabrik

Fabrik

factory ist sehr ähnlich wie service, der Unterschied besteht darin, dass service ein Singleton-Objekt in Angular ist. Wenn Sie also service verwenden müssen, verwenden Sie das Schlüsselwort new, um einen (und nur einen) Service zu erstellen. Factory ist eine gewöhnliche Funktion. Bei Bedarf handelt es sich lediglich um eine Methode zum Aufrufen einer gewöhnlichen Funktion. Sie kann verschiedene Formen von Daten zurückgeben, indem sie beispielsweise ein Sammlungsobjekt funktionaler Funktionen zurückgibt.

Definition:

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()
  };
});

Injektion verwenden:

app.controller("control", (Today) => {
  console.log(Today.year);
  console.log(Today.month);
  console.log(Today.day);
});

service

service ist bei Verwendung ein Singleton-Objekt und auch ein Konstruktor. Aufgrund seiner Eigenschaften kann er nichts zurückgeben, da er mit dem Schlüsselwort new erstellt wird und im verwendet werden kann Controller Kommunikation und Dateninteraktion zwischen Controllern, da die Bereichskette des Controllers zerstört wird, wenn sie nutzlos ist (z. B. Routing verwenden, um zu einer anderen Seite zu springen, während ein anderer Controller verwendet wird)

Definition:

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();
});

Injektion verwenden:

app.controller("control", (Today) => {
  console.log(Today.year);
  console.log(Today.month);
  console.log(Today.day);
});

Anbieter

Anbieter Ja Was die zugrunde liegende Methode zur Erstellung des Dienstes betrifft, können wir verstehen, dass der Anbieter eine konfigurierbare Version des Dienstes ist. Wir können einige Parameter des Anbieters konfigurieren, bevor wir den Anbieter offiziell einfügen.

Definition:

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()
    };
  };
});

Injektion verwenden:

// 这里重新配置了今天的日期是 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);
});

3. Konflikt zwischen Lenker und Winkelsymbolauflösung

Szenario:

Wenn ich node.js als Server verwende und Lenker als Vorlagen-Engine verwendet wird, wenn node .js reagiert auf eine bestimmte URL und rendert diese, da ihre Vorlage { {} } als Variablen-Parsing-Symbol verwendet. In ähnlicher Weise verwendet Angular auch { {} } als Symbol für die variable Auflösung. Wenn also node.js die Seite rendert und die Variablen in { {} } nicht vorhanden sind, wird der Bereich gelöscht, und meine ursprüngliche Absicht ist dies Es wird verwendet für die Analyse von Angular anstelle von Handles. Gleichzeitig möchte ich auch weiterhin Handles verwenden, daher muss ich zu diesem Zeitpunkt das Standard-Parsing-Symbol {{} } von Angular neu definieren. Das heißt, verwenden Sie die Abhängigkeitsinjektion $interpolateProvider, um sie zu definieren, wie im folgenden Beispiel gezeigt:

app.config($interpolateProvider => {
  $interpolateProvider.startSymbol(&#39;{[{&#39;);
  $interpolateProvider.endSymbol(&#39;}]}&#39;);
});

4. ng-annotate-loader

ng -annotate-loader wird auf das Entwicklungsszenario von Webpack + Angular angewendet. Es ist eine Lösung, um das Problem zu lösen, dass die Abhängigkeitsinjektion fehlschlägt und Fehler auftreten, nachdem Angular JS komprimiert wurde

Installation

$ npm install ng-annotate-loader --save-dev

Konfiguration

// webpack.config.js
{
  test: /\.js?$/,
  exclude: /(node_modules|bower_components)/,
  loader: &#39;ng-annotate!babel?presets=es2015&#39;
},

Zwei-Wege-Datenbindung

Wenn wir nicht in Angular integrierte Ereignisse verwenden, führen Datenänderungen in $scope nicht zum Dirty-Checking-Zyklus von $digest. Dies führt dazu, dass die Ansicht beim Modellieren nicht synchron aktualisiert wird In diesem Fall müssen wir das Update aktiv selbst auslösen

HTML

<div>{{ foo }}</div>
<button id="addBtn">go</button>

JavaScript

app.controller("control", ($scope) => {
  $scope.foo = 0;
  document.getElementById("addBtn").addEventListener("click", () => {
    $scope.foo++;
  }, false);
})

Ganz offensichtlich ist die Absicht des Beispiels, dass foo die Ansicht vergrößert und aktualisiert, wenn auf die Schaltfläche geklickt wird. Tatsächlich wird jedoch $scope.foo geändert. aber die Ansicht wird nicht aktualisiert. Dies liegt daran, dass foo kein $watch zum Erkennen von Änderungen hat, was letztendlich $digest verursacht, also müssen wir $apply selbst auslösen oder ein $watch erstellen, um Datenänderungen auszulösen oder zu erkennen >

JavaScript (mit $apply)

app.controller("control", ($scope) => {
  $scope.foo = 0;
  document.getElementById("addBtn").addEventListener("click", () => {
     
    $scope.$apply(function() {
      $scope.foo++;
    });
 
  }, false);
})

JavaScript (mit $watch & $digest)

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);
})

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

Registrieren Sie eine Listener-Rückruffunktion, die jedes Mal aufgerufen wird, wenn sich der Wert von watchExpression ändert

watchExpression wird jedes Mal aufgerufen, wenn $digest ausgeführt wird, und gibt den zu erkennenden Wert zurück (wenn mehrere) Wenn derselbe Wert zweimal eingegeben wird, sollte watchExpression seinen eigenen Wert nicht ändern, da sonst mehrere $digest-Schleifen auftreten können. watchExpression sollte sein idempotent)


Listener wird auf dem aktuellen watchExpression-Rückgabewert basieren und aufgerufen, wenn die Rückgabewerte der watchExpression-Zeiten inkonsistent sind (verwenden Sie !==, um die Inkonsistenz streng zu beurteilen, anstatt == zu verwenden, außer für objectEquality == true)


objectEquality ist ein boolescher Wert. Wenn true, wird angle.equals verwendet, um die Konsistenz zu bestimmen, und angle.copy wird verwendet, um diese Kopie des Objekts für zu speichern Nächster Vergleich. Dies bedeutet, dass es bei der Erkennung komplexer Objekte zu Leistungs- und Speicherproblemen kommt.


7 um die $digest-Schleife auszulösen

$Pseudocode anwenden

function $apply(expr) {
  try {
    return $eval(expr);
  } catch (e) {
    $exceptionHandler(e);
  } finally {
    $root.$digest();
  }
}

Verwenden Sie $eval(expr), um den Ausdruck expr auszuführen

Wenn während der Ausführung eine Ausnahme auftritt, führen Sie $ExceptionHandler(e) aus

Am Ende wird unabhängig vom Ergebnis eine $digest-Schleife ausgeführt


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn