Maison > interface Web > js tutoriel > le corps du texte

Décrire brièvement quelques idées de programmation liées à AngularJS_AngularJS

WBOY
Libérer: 2016-05-16 15:53:32
original
1018 Les gens l'ont consulté

Ces derniers mois, j'ai voyagé dans le monde d'Angular. Avec le recul, il est difficile d'imaginer comment j'écrirais chaque jour une grande application frontale sans les frameworks de liaison de données comme Angular.js, Backbone.js et leur compagnon Underscore.js. Je ne peux pas croire que j'ai fait ce travail avec eux.

Je suis peut-être un peu partial, mais étant donné que l'application sur laquelle j'ai travaillé est un éditeur de type Photoshop dans le navigateur, elle présente les mêmes données de plusieurs manières complètement différentes.

  • Les calques sont présentés graphiquement et occupent la majeure partie de l'écran. Ils sont répertoriés dans un panneau et vous pouvez les supprimer.
  • Lorsque vous sélectionnez un calque, ses bords seront entourés de lignes pointillées et seront mis en surbrillance dans la liste.
  • De même, les dimensions des calques du panneau et leurs propriétés de taille dépendent du canevas.
  • Les panneaux que j'ai mentionnés ci-dessus peuvent être glissés, pliés et fermés.


Sans un framework comme Augular, ce type d'interaction, de connexions de données et de synchronisation des vues pourrait facilement se transformer en un cauchemar constant. Avoir la possibilité de corriger un modèle local et de corriger toutes les vues associées avec Augular semble presque être un mensonge. Ajouter, supprimer ou modifier un niveau consiste simplement à changer l'objet. Niveau, x = 10, terminé. Il n'est pas nécessaire d'invalider manuellement les vues, de modifier manuellement chaque instance de la hiérarchie DOM ou même d'interagir avec le DOM.

Augular nous permet d'aller dans des endroits que nous n'avions jamais imaginés, comme la mise en place d'une série de raccourcis clavier qui nous permettent de créer des applications dans des environnements existants. Par exemple, les raccourcis d'édition de fichiers (comme ?B : pour basculer le texte en gras) nous permettent simplement de modifier un niveau de fichier.

201562395829701.png (151×117)

De même, nous attachons une description à ces raccourcis (enregistrés via un service que nous avons créé), puis nous pouvons afficher une liste de raccourcis, ainsi que leurs descriptions, dans une barre pratique. De plus, nous avons écrit une commande qui nous permet de lier des éléments DOM individuels à leurs touches de raccourci. Lorsque votre souris reste sur l'élément pendant un certain temps, une invite apparaîtra pour vous informer des touches de raccourci disponibles à ce moment-là.

  • Angular nous permet de faire des choses dont nous n'avions jamais rêvé.

Honnêtement, c’est comme si nous n’écrivions plus d’application Web. Le Web n'est qu'un média. À mesure que nous améliorons notre compréhension d'Angular, le code devient plus modulaire, plus autonome, plus connecté et interactif. Cela devient naturellement plus angulaire.


Et puis par Augular, j'entends ces philosophies de développement d'applications riches et hautement interactives derrière Augular. JavaScript, une chose similaire qui nous permet de développer des parties de logiciels que nous pensions impossibles il y a quelque temps.

201562395953032.png (816×304)

Nous avons même la possibilité de développer un panneau de contrôle d'historique à part entière pour modifier le DOM au point actuellement sélectionné de l'historique, et de le faire fonctionner très bien. C'est pour le moins excitant de revenir au tableau de bord de l'historique pour afficher les données liées à la capacité d'Augular à mettre à jour chaque petit détail du travail de votre vue.

Ce n'est pas toujours facile, le code de base se transforme toujours en un désordre incontrôlable.

En effet, au cours des dernières semaines, nous avons mis à jour et réécrit toute notre architecture front-end. Avant de commencer la réécriture, examinons le processus de mise à jour d'Angular à son avantage depuis la 0.10.6. Si vous lisez le journal des modifications, vous savez que c'est un processus assez long.

Au cours de cette refactorisation, nous sommes passés du traitement d'Angular de la mauvaise manière au traitement d'Angular de la manière angulaire.

Dans notre cas, la mauvaise approche impliquait de nombreux problèmes que nous avons dû résoudre à ce stade avant de remettre notre base de code dans un bel état.

Déclarer les contrôleurs dans la portée globale

C'est un exemple simple à réaliser pour les débutants d'Angular. Si vous connaissez Angular, vous connaîtrez également ce modèle.

// winds up on window.LoginCtrl ...
var LoginCtrl = function ($scope, dep1, dep2) {
  // scope defaults
};
 
LoginCtrl.prototype.resetPassword = function () {
  // reset password button click handler 
};
 
// more on this one later
LoginCtrl.$inject = ['$scope', dep1', 'dep2'];
Copier après la connexion

Ce code n'est pas inclus dans la fermeture, ou en d'autres termes, toutes les déclarations sont dans la portée racine, l'objet fenêtre global, salaud. Pour écrire de manière angulaire authentique, utilisez l'API du module fournie par celui-ci. Mais comme vous pouvez le constater, même la documentation et les étapes recommandées sont encore obsolètes en ce qui concerne l'utilisation de la portée globale :

Faites cela et de grandes choses se produiront.

  // A Controller for your app
  var XmplController = function($scope, greeter, user) {
   $scope.greeting = greeter.greet(user.name);
  }
Copier après la connexion

-- Angular.js文档

使用模块(modules)允许我们以下面的方式重写控制器(controllers):

angular.module('myApp').controller('loginCtrl', [
  '$scope', 'dep1', 'dep2',
  function ($scope, dep1, dep2) {
    'use strict';
 
    // scope defaults
 
    $scope.resetPassword = function () {
      // reset password button click handler
    };
  }
]);
Copier après la connexion

我发现使用 Angular 控制器的漂亮做法是你必须在所有地方使用控制器方法(controller function),因为你需要控器的依赖注入,而且控制器提供了新的作用域,绑定我们从需求到封装我们所有的脚本文件成为自调用函数表达式( self-invoking function expressions),像这样 (function(){})()。

依赖$injection
在最早的例子中你可能已经注意到了, 依赖是使用$inject注入的. 另一方面,大部份的模块API, 允许你传入一个函数作为参数, 或者一个包含了依赖的数组作为参数, 其后面跟着一个依赖于这些依赖的函数. 这是在Angular中我不喜欢的一点 , 但这应该是它文档的过错. 在文档中的大部份例子认为你并不需要一个数组形式的参数; 但现实是,你是需要的。 如果你在使用一个压缩器压缩你的代码之前, 没有运行ngmin , 事情将会变得糟糕.


由于你没有使用数组格式['$scope',...]明确声明你的依赖包,你看上去简洁的方法参数将会被缩略成类似于b,c,d,e的样子,有效地扼杀了Angular的依赖注入能力。我认为他们构建框架的思路存在了重大的失误,这与我在非常不喜欢 Require.js 和他们麻烦的 AMD 模块最后的推论是相似的。

如果他不能在产品中使用,它还有什么用?

我的这种态度是因为你在产品中所使用的框架里,有一部分代码是已经写死了的。这对于开发中经常用到、产品中偶尔用到的实用工具,诸如控制台和错误报告,是很好的。如果语法上的甜头(可读性)只用在开发中,就会变得没有任何意义。

这些破事让我很愤怒, 现在发泄完了. 谈谈$符吧...

减少 jQuery扩散

深入的讲, 这个应用是 "类Angular程序", 也就是说它只是包裹于Angular之中, 大多数DOM 交互是经由jQuery处理的, 这给Angular带来相当多的争论。

如果今天我要从头开始写一款Angular.js应用,我不会立即包含进jQuery。我会强迫自己使用 angular.element 来代替。

如果jQuery存在的话,angular.element这个API将包装它,同时它给Angular团队实现 jQuery的API提供了可以替代的选择,名为jqLite。这并不是说 jQuery不好,或者说我们需要另一个某种实现,来映射它们的API。只是因为使用jQuery显得不是那么有Angular的思想。


让我们来看一个具体的,愚蠢的,例子。在controller被声明的地方,它使用jQuery来做元素之上的类操作。

div.foo(ng-controller='fooCtrl')
 
angular.module('foo').controller('fooCtrl', function ($scope) {
  $('.foo').addClass('foo-init');
 
  $scope.$watch('something', function () {
    $('.foo').toggleClass('foo-something-else');
  });
});
Copier après la connexion

然而,我们可以用我们期望的方法来使用Angular,替代之。

angular.module('foo').controller('fooCtrl', function ($scope, $element) {
  $element.addClass('foo-init');
 
  $scope.$watch('something', function () {
    $element.toggleClass('foo-something-else');
  });
});
Copier après la connexion

最后一行你不能直接,或者通过jQuery来操作DOM(改变属性,增添事件监听器)。你应该使用指令来替代。那篇文章很棒,去读读看。

如果你仍然jQuery化了,有许多文章可以一读,例如这篇迁移指南,还有我的关于怎样使用jQuery的批判性思考 这篇文章。


我不是要声明我们准备完全移除 jQuery 。我们有其他更重要的目标,例如,发布我们的产品。这个时候,删除 jQuery 的依赖还是很有意义的。这样做能够使我们的控制器得到简化,我们创建处理 DOM 的指令,使用 angular.element 即使它实际上映射着 jQuery 。

我们依赖着有点恶心的 jQuery UI,我们当然不只是为了它的对话框而使用它,它还有很多用途。例如,拖动一个列表项然后把它放到一个已排序的列表中,如果不使用 jQuery UI,这将牵涉到一大堆代码。因此,实际上,对于 jQuery UI 来说,并没有真正很好的替代品。拖拽的功能可以通过一个轻量级的拖拽库 angular-dragon-drop 来替代,但是,对于元素排序插件,还是得依赖 jQuery UI 。

管理代码库

还有一个我们在迁移中需要解决的问题是整个代码库都挤在一个单一的大文件中。这个文件包含了所有控制器、所有服务、所有指令以及每个控制器的特定代码。我指出一点使得我们可以准确地把每个文件只包含一个组件。目前,我们有很少的文件,却包含了不知一个组件。大多数是因为一个指令使用一个服务来与外界共享数据。

尽管和 Angular 无关,我们还是把我们的 CSS 样式表(stylesheet)模块化。我们为每个组件中使用的 CSS 类名前面都加上了两个字的前缀。例如, .pn- 作为前缀,代表面板(panel); .ly- 前缀,代表着图层(layer)等等。这样做的直接好处就是,你不需要再费劲地想哪个组件的 CSS 类是怎样的了。因为你已经为它们设置了命名空间,你就很少会重复用到某一个 CSS 类名了。另一个好处就是减少了嵌套,我们以前曾经用 #layoutEditor div.layer .handle div 这样复杂的选择器表达式,而现在,我们只需要 .ly-handle-content 就可以了。深度的嵌套现在只发生在额外的选择器覆盖上,例如 .foobar[disabled]:hover,或者,最坏的情况下,像 .foo-bar .br-baz 。


下面是一些我们定下的 CSS 类命名规则:

  • 用两个字符来描述组件名:.ly-、.dd-、.dg-等等
  • 采用 .ly-foo-barname 来代替嵌套命名 .ly-foo .bar
  • 避免内联样式,总是使用 CSS 类名。这能够减少不界面的一致性,提高语义解释能力
  • 不要在 CSS 中使用 ID 来赋值

在实现了这套面向组件的 CSS 声明方法后,我又想了很久“the class soup way”。

Angular 强制你写好的代码,但是更深一层说,它强制你去思考。一会儿后,它就像一个服务器端的实现,或者成为一个不堪忍受的“黑客大会”。这些都取决于你这么选择。

接近完美

让我们来解析一下我们应用程序的各部件的其中之一,层。

div.cv-layer(
  ng-repeat="layer in page.layers | reverse",
  ap-layer,
  ng-mousedown="selectLayer(layer.id)",
  ng-mouseup="selectLayer(layer.id)",
  ng-dblclick="doubleClickLayer(layer)",
  ng-hide="layer.invisible"
)

Copier après la connexion

Ici, nous utilisons la classe cv-layer, ce qui signifie que cet élément fait partie du composant canvas (canvas fait référence à l'endroit où l'on dessine le calque, à ne pas confondre avec le canevas HTML5). Ensuite, nous utilisons la balise ngRepeat dans une boucle de type foreach pour créer un élément similaire pour chaque couche. Et passé à travers un filtre inverse que nous avons écrit, de sorte que le dernier calque est au-dessus et visible par l'utilisateur. La balise apLayer est en fait utilisée pour dessiner un calque, qu'il s'agisse d'une image, d'un texte, de HTML ou de quelque chose d'autre. Les balises d'événement (ng-mousedown, ng-mouseup, ng-dblclick) sont simplement utilisées comme proxy pour les événements qui seront gérés par notre service de sélection de couches. Enfin, je pense qu'il n'est pas nécessaire d'en dire plus sur la balise ngHide.


Il y a tellement de fonctions (Note du traducteur : c'est un peu exagéré), et Angular a réussi à les rendre si simples, en utilisant du HTML lisible pour vous dire de quoi il s'agit dans une certaine mesure. Plus important encore, cela vous permet de décomposer les différents problèmes à prendre en compte afin que vous puissiez écrire du code concis sans avoir à tout considérer en même temps. En bref, cela réduit la complexité (Note du traducteur : Angular lui-même est en fait très complexe, haha) et simplifie la complexité. Et rendre possibles des « problèmes difficiles à mesurer facilement ».

J'attends avec impatience d'autres articles sur le codage angulaire bientôt. En particulier, j'aime explorer certains des cas extrêmes que je rencontre lors de la mise à niveau de mon code et comment les corriger tout en faisant fonctionner le reste du code de la même manière.

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal