Angular Using embedded JavaScript in HTML attributes is not "bad practice"?

When I read the Angular tutorials, I really liked it, but not the "ng-click" equivalent of the built-in onClick? My understanding was that the JavaScript community defined built-in JavaScript event handlers in your HTML, it was "bad practice."

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

It would be great to know why this is no longer considered "wrong" when using Angular.

Source: http://docs.angularjs.org/tutorial/step_10

+49
javascript angularjs
Feb 10 '13 at 1:30
source share
1 answer

Indeed, it all comes down to the fact that your view code needs to be somehow connected to your application logic. The best practices for AngularJS generally say that you should write your own models - objects that represent your business domain, and attach them to the field. Imagine this code:

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

The view says: "When this image is clicked, it will call setMainImage () in myProfile." The business logic is inside myProfile , where it can be tested, etc. A view is just a hook.

In a more "traditional" or "vanilla" jQuery setup, you need to write something like the following:

 $("#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? }); 

Of course, the JavaScript community has determined that writing large applications this way is not really acceptable, in part because of the disconnection between the views and the model objects (as indicated by the comments in the code snippet), which is why we have frameworks like Angular.

So, we know that this native jQuery code is not perfect, but we are still not sure about whole ngClick things. Let me compare it with another very popular JavaScript framework that provides the MV * architecture, Backbone. In a recent RailsCasts episode on AngularJS, someone asked a very similar question :

Is it just me, or does AngularJS look like such a bad idea? Ryan, don’t get me wrong, the episode was wonderful, but I'm not sure about the limits.

All that ng-show , ng-repeat , ng-class look like old Java JSF and similar structures. It also provides intrusive JS with ng-submit and ng-click .

So, I want to say: your view will be easily cluttered and completely dependent on it. The advantage of other frameworks, such as Backbone, is the separation of problems between presentation and behavior (less or no dependencies) and a structured client application (MVVM).

My answer is also applicable here :

In a structure like Backbone, you will have something like the following code (taken from the Backbone website, minus a few lines):

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

In this view object, you configure event handlers for various elements. These event handlers call functions on the view object that delegate models. You also configure callbacks for various model events (for example, change ), which, in turn, call functions on the view object to update the view accordingly.

In Angular DOM, your opinion. When using ng-click , ng-submit , etc. You set up event handlers for these elements that call functions that should delegate object modeling. When using ng-show , ng-repeat , etc. You set up callbacks for model events that change presentation.

The fact that AngularJS sets these [hooks and] backstage callbacks doesn't matter to you; the only difference between this and something like Backbone is that Angular allows you to write declaratively - you describe your opinion, and not necessarily - describe what your look does.

So in the end, <a ng-click="model.set({selected: true})"> really adds more dependencies than

 events: { 'click a': 'select' }, select: function() { this.model.set({selected: true}); } 

... but this is certainly a hell of a lot less code .;)

(Note: indeed, the version of Angular should be <a ng-click="select()"> , and the select method in scope will be similar to the select method in the view in the base example).

Now, perhaps the legitimate problem is that you don't like event hooks in your markup. Personally, I prefer the declarative nature of Angular views, where your markup describes what the view is, and you have two-way binding between events (regardless of whether they were created by the user or just changes in the model) and your views - I find I’m writing much less template code for attaching events (especially changes in the view caused by changes in models), and I think it’s easier to talk about viewing in general.

+59
Feb 10 '13 at 2:17
source share



All Articles