Подтвердить что ты не робот

Angular Использование встроенного JavaScript в атрибутах HTML не является "плохой практикой"?

Когда я прочитал учебники Angular, мне это очень понравилось, но не "ng-click" эквивалент встроенного onClick? Мое понимание было то, что сообщество JavaScript определило встроенные обработчики событий JavaScript в вашем HTML, было "плохой практикой".

<img ng-src="{{img}}" ng-click="setImage(img)">

Было бы здорово узнать, почему это больше не считается "неправильным" при использовании Angular.

Источник: http://docs.angularjs.org/tutorial/step_10

4b9b3361

Ответ 1

Действительно, все сводится к тому, что ваш код представления нужно каким-то образом подключить к вашей логике приложения. Лучшие практики для AngularJS в целом говорят о том, что вы должны написать свои собственные модели - объекты, которые представляют ваш бизнес-домен, и присоединить их к области. Представьте себе такой код:

<img ng-src="{{img}}" ng-click="myProfile.setMainImage(img)">
myApp.controller("ProfileController", function($scope, myProfile) {
  $scope.myProfile = myProfile;
});

В представлении говорится: "Когда это изображение будет нажато, оно вызовет setMainImage() в myProfile". Бизнес-логика находится внутри myProfile, где ее можно протестировать и т.д. Представление - это просто крючок.

В более "традиционной" или "vanilla" настройке jQuery вам нужно написать что-то вроде следующего:

$("#someId img").on('click', function() {
  var img = $(this).attr('src');
  myProfile.setMainImage(img); // where does myProfile come from here?
                               // how does it update the view?
});

Конечно, сообщество JavaScript определило, что писать большие приложения таким образом не является действительно приемлемым, отчасти из-за отключения между представлениями и объектами модели (как указано комментариями в фрагменте кода), которые поэтому у нас есть фреймворки, такие как Angular.

Итак, мы знаем, что этот собственный код jQuery не идеален, но мы все еще не уверены в целых ngClick вещах. Позвольте сравнить его с другой очень популярной инфраструктурой JavaScript, которая обеспечивает архитектуру MV *, Backbone. В недавнем эпизоде ​​RailsCasts на AngularJS кто-то задал очень похожий вопрос:

Это только я, или AngularJS выглядит так плохой идеей? Райан, не пойми меня неправильно, эпизод был замечательный, но я не уверен в рамках.

Все, что ng-show, ng-repeat, ng-class выглядят как старые Java JSF и аналогичные структуры. Он также обеспечивает навязчивое JS с ng-submit и ng-click.

Итак, я хочу сказать: ваш взгляд будет легко загромождать и полностью зависеть от него. Преимущество других фреймворков, таких как Backbone, заключается в разделении проблем между представлением и поведением (меньше или без зависимостей) и структурированным клиентским приложением (MVVM).

Здесь также применим мой ответ:

В такой структуре, как Backbone, у вас будет что-то вроде следующего кода (взятого с сайта Backbone, минус несколько строк):

var DocumentView = Backbone.View.extend({

  events: {
    "dblclick"                : "open",
    "click .icon.doc"         : "select",
    "contextmenu .icon.doc"   : "showMenu",
    "click .show_notes"       : "toggleNotes",
    "click .title .lock"      : "editAccessLevel",
    "mouseover .title .date"  : "showTooltip"
  },

  open: function() {
    window.open(this.model.get("viewer_url"));
  },

  select: function() {
    this.model.set({selected: true});
  },

});

В этом объекте, являющемся представлением, вы настраиваете обработчики событий для различных элементов. Эти обработчики событий вызывают функции на объекте представления, которые делегируют модели. Вы также настраиваете обратные вызовы для различных событий модели (например, change), которые, в свою очередь, вызывают функции на объекте представления, чтобы соответственно обновить представление.

В Angular DOM - ваше мнение. При использовании ng-click, ng-submit и т.д. Вы настраиваете обработчики событий для этих элементов, которые вызывают функции, которые должны делегировать моделирование объектов. При использовании ng-show, ng-repeat и т.д. Вы настраиваете обратные вызовы для событий модели, которые меняют представление.

Тот факт, что AngularJS устанавливает эти [крючки и] обратные вызовы за кулисами для вас, не имеет значения; единственная разница между этим и чем-то вроде Backbone заключается в том, что Angular позволяет вам писать декларативно - вы описываете свое мнение, а не обязательно - описываете, что делает ваш взгляд.

Итак, в конце, <a ng-click="model.set({selected: true})"> действительно добавляет больше зависимостей, чем

events: {
  'click a': 'select'
},

select: function() {
  this.model.set({selected: true});
}

... но это, безусловно, чертовски намного меньше кода.;)

(Примечание: действительно, версия Angular должна быть <a ng-click="select()">, а метод select в области видимости будет похож на метод select в представлении в примере с базой).

Теперь, возможно, законная проблема заключается в том, что вам не нравятся перехватчики событий в вашей разметке. Лично я предпочитаю декларативный характер представлений Angular, где ваша разметка описывает, что такое представление, и у вас есть двусторонняя привязка между событиями (независимо от того, были ли они созданы пользователем или просто изменения в модели) и ваши взгляды - я нахожу Я пишу гораздо меньше кода шаблона для подключения событий (особенно изменений в представлении, вызванных изменениями в моделях), и я думаю, что легче рассуждать о просмотре в целом.