Is the Utilization of Inline JavaScript in HTML Attributes by Angular considered a "good practice"?

While going through the Angular tutorials, I found a lot to like. However, I couldn't help but wonder if "ng-click" is not essentially just an inline onClick function. My understanding was that the JavaScript community frowned upon using inline JavaScript event handlers in HTML as it was considered a "bad practice."

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

I am curious to know why this approach is now acceptable when working with Angular.

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

Answer №1

Ultimately, the key point is that your view code needs to be connected to your application logic in some way. AngularJS best practices recommend creating your own models - objects that represent your business domain - and attaching them to the scope. Consider this example:

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

In this scenario, the view instructs that when the image is clicked, it should call setMainImage() on myProfile. The actual business logic resides within myProfile, enabling it to be tested and managed separately. The view simply serves as a bridge.

In a more conventional jQuery setup, you would need to write something like the following:

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

The JavaScript community generally agrees that managing large applications using this approach is not practical, mainly due to the disconnection between views and model objects (as evident from the comments in the code sample), which is why frameworks like Angular exist.

While the traditional jQuery code may not be ideal, there are still uncertainties about the ngClick approach. Let's compare it with another popular MV* architecture framework, Backbone. A user raised concerns about AngularJS in relation to Backbone in a RailsCasts episode:

Is AngularJS really a good idea? The use of ng-show, ng-repeat, ng-class reminds me of old frameworks like Java's JSF. It also enforces obtrusive JS with ng-submit and ng-click.

The concern is that your view could become cluttered and overly reliant on these directives. Other frameworks like Backbone prioritize separation of concerns between presentation and behavior, resulting in a structured client-side application (MVVM).

A similar response was provided...

In a Backbone environment, event handlers are set up on elements within a view object to interact with model functions. Callbacks are also established on model events to trigger updates in the view. In contrast, Angular treats the DOM itself as the view by setting up event handlers through directives like ng-click, ng-submit that delegate to model objects or respond to model changes affecting the view.

The main difference lies in how declarative Angular views describe what the view represents compared to imperative approaches like Backbone, where the focus is on defining what actions the view performs. Although Angular sets up callbacks automatically, it ultimately simplifies the process without introducing additional dependencies.

So, using

<a ng-click="model.set({selected: true})">
doesn't impose more dependencies than...

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

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

...but it significantly reduces the amount of code required. ;)

(Note: Ideally, the Angular version should utilize

<a ng-click="select()">
, where the select method on the scope mirrors the functionality of the view's select method in the Backbone example.)

If the presence of event hooks in your markup is a genuine concern, Angular's declarative nature offers a more streamlined approach where markup defines the view's characteristics and facilitates two-way binding between events and views. This results in less boilerplate code for event handling and improves overall view comprehension.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Extracting Data from JSON Structures

I am struggling with extracting data from a JSON string that looks like this: var txt= '{“group”: [ {“family1”: { “firstname”:”child1”, “secondname”:”chlid2” }}, {“family2”: { ...

Error: XYZ has already been declared in a higher scope in Typescript setInterval

I've come across an interesting issue where I'm creating a handler function and trying to set the current ref to the state's value plus 1: const useTimer = () => { const [seconds, setSeconds] = useState(0); const counterRef = useRef(n ...

Adjust the properties within the component's styles using Angular 2

In this project, the objective is to dynamically change the background-color based on different routes. The goal is to display a specific color for UpcomingComponent while keeping the background-color consistent for all other routes. The approach involves ...

The attempt to cast the value of "X_Value" to an ObjectId in the "X_Model" model at the path "_id" has failed due to being of type string

I'm facing an issue while attempting to update multiple records simultaneously using their IDs. The error message I encounter is puzzling, even ChatGPT couldn't provide a solution. Here's the error: Cast to ObjectId failed for value " ...

The ng-repeat function is not functioning properly when used within an li element to trigger

I have utilized the Dialog service to create a pop-up window. My intention is to display a message to the user in this format: txt = '<ul> <li data-ng-repeat = "eachValue in dummnyList" > {{eachValue | applyFilte ...

Chrome Extension to Emphasize Every Word

As a novice, I am embarking on the journey of creating my own chrome extension. The idea is to design a popup.html file that showcases a "highlight" button. The functionality would involve clicking this button to highlight all words on the page. Here&apos ...

Utilizing Mongoose Schema for CSV Import

My current task involves importing a large CSV file into a mongo DB, where the order of the values will determine the key for each entry in the database: Here is an example of the CSV file structure: 9,1557,358,286,Mutantville,4368,2358026,,M,0,0,0,1,0 9 ...

Error message: "Issue with Jointjs library on Node.js server - Uncaught ReferenceError: Joint is not recognized"

I am attempting to create a sample diagram using the code below on a file hosted on a Node server: <!DOCTYPE html> <html> <head> <title>newpageshere</title> <link rel="stylesheet" href="joint.css" /> <script src="j ...

Determine with jQuery whether the img src attribute is null

My HTML structure is as follows: <div class="previewWrapper" id="thumbPreview3"> <div class="previewContainer"> <img src="" class="photoPreview" data-width="" data-height=""><span>3</span> </div> </div> ...

When using NextJS, the dynamically generated HTML elements do not get affected by CSS repaint

Recently, I encountered an issue while working on a Next.js project involving the addition of an external script that uses vanilla JavaScript to dynamically create nodes. Despite importing global CSS at the top of my _app.js file, I noticed that the styles ...

Tips for customizing the cursor to avoid it reverting to the conventional scroll cursor when using the middle click

When you wish to navigate by scrolling with the middle mouse button instead of using the scroll wheel, simply middle-click and your cursor will change allowing for easy scrolling on web pages. Even though I am utilizing style="cursor: pointer" and @click. ...

The concept of overloading operators in V8

Here's a question that I've been pondering, but couldn't seem to find any answers for on Google. While it may not be achievable in pure JavaScript, let's say I'm developing a container class in V8 and then returning that class bac ...

ReactJS: Alert for controlled form element

Utilizing inputs from Material-Ui, I am retrieving values from an API to populate these inputs. If the API does not return any values, the user must enter them manually. In my implementation, I am utilizing Hooks with the initial state defined as: const [ ...

Commencing CSS Animation Post Full Page Loading

I am looking for a solution using WordPress. In my specific case, I want the CSS Animations to take effect only after the page has completely loaded. For example: click here This is my HTML: <div class="svg-one"> <svg xmlns="ht ...

Exploring the mechanics of callbacks in jQuery's Ajax functionality

Greetings fellow developers! I've embarked on a new programming project with the firm intention of writing cleaner and more easily maintainable code than ever before. However, I have encountered my old nemesis - jQuery AJAX returns. The last time I t ...

The background color of the active tab is updated upon loading the page

I have attempted to modify this code to change the background color of li tag on click. It successfully changes the background color when hovering or clicking, but unfortunately reverts back to the default color upon page refresh. I am looking for a soluti ...

Fetching the second item within an object using JavaScript

I am trying to retrieve the data from the last month of an API, but I want to avoid hard-coding the date like this: const data = [data.data['Monthly Time Series']['2021-11-30']]. I need a way to dynamically access the 2nd object without ...

"Getting Started with Respond.js: A Step-by-Step

I've been struggling to find clear instructions on how to properly set up respond.js. Should I just unzip it into the htdocs folder, or do I only need respond.min.js in there? Then, do I simply reference the file like this... <script src="respon ...

Extract data from dynamically loaded tables using PhantomJS and Selenium Webdriver

I've been informed by everyone that I should be able to retrieve the table content using PhantomJS when working with JavaScript. However, despite my attempts, I have not been successful. My expectation was to obtain the table from the website Page 1 ...

Ways to transfer information from an axios API to a state in React

I am currently working with an API that consists of an array of objects. My goal is to pass this data into a state in order to display it within a component on a website. First Approach: // Fetches the API data const newData = axios.get(url).then( ...