Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of using Modules to organize Code in AngularJS

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article is to share with you the example analysis of using modules to organize code in AngularJS. The editor thinks it is very practical, so I share it with you to learn. I hope you can get something after reading this article.

Download modulePattern.zip-all 4 HTML files and panacea.js-1.6 KB

Introduction

There are a lot of things in AngularJS's library, but I just want to focus on small, topic-specific libraries, which I believe will give a better introduction to Angular. Understanding this article does not require you to have any Angular-related experience, or even JavaScript experience. I hope you can see some benefits of using Angular and be happy to try it.

Background

I've been using Angular for a while, and when I'm learning Angular, I like to build samples, so when I first delve into it, I don't think much about the module or JavaScript design pattern, which helps to keep the code organized and organized. That's what it's all about: keep the code organized and organized. So now I've looked back and created this extremely small example to show how easy it can be to use a module. Along the way, I hope it will be a good introduction to Angular.

(most) the problems of the article in expounding the pattern

Most of the time people try to explain a pattern before the reader knows what a pattern is, which basically misleads everyone. To make this article as simple as possible, let's take a look at this problem first. What's the problem? It's about the Javascript of everything that is created by default in the global memory space.

Here is what I mean.

Default global issues for JavaScript

Imagine that you have the following script in your HTML.

Var isDoingWork = false

Range?

Do you know the scope of this variable?

Yes, it is global. This Boolean value is actually added to the browser's global window object.

Set it to Action

Here you can see what it looks like in Action.

Download the code sample for this article.

Open modulePattern.htm in your browser.

Open the browser development tool-- F12 (Chrome, IE) or Ctrl-Shift-I (Opera)-- (so you can see the console)

Under the browser tool console, enter: isDoingWork, and then enter enter

You will see that the output value is false.

Now enter: isDoingWork = true, and then press enter

So the download value is true. You have changed this value.

You can see that this value has been added to the global window object by typing doingwindow.isDoingWork = true and then entering enter.

This may cause some name conflicts and can lead to some serious bug. This may be a little alarmist for you, isn't it? But imagine that you decide to implement a new JS library that can be created every minute. Suppose you find this great library called Panacea.js, which will solve all your problems.

So you quote it on your page like this:

It's so simple that you've solved all the problems you've encountered before. However, because it's a huge library, and you just want a solution, you don't go back to digging into every line of code in this huge (thousands of lines of code) source file. And the code buried deep in a corner of Panacea.js actually looks like this:

Var isDoingWork = false; setInterval (function () {isDoingWork =! isDoingWork;}, 3000)

This code is really cool, you know?

Every 3 seconds, it sets the Boolean value to a relative value. Aah!

See for yourself.

If you want to verify this thing yourself, you can do the following steps:

Download the sample code for this article.

Open modulePattern2.htm in your browser.

Open browser development tools-- F12 (Chrome, IE) or Ctrl-Shift-I (Opera)-- (so you can see the console)

Under the console of the browser development tool, enter: isDoingWork and enter

Repeat step 4 a few more times and you will find that the value of isDoingWork will change every about 3 seconds.

Isn't that great?

My opinion: module mode is very useful

I need to explain this, in order to show you why JavaScript's module mode is useful. I have to show you the module pattern of JavaScript so that I can tell you how it is used or implemented in AngularJS.

Module mode: encapsulation

In this way, in fact, the module mode is basically encapsulated. Encapsulation sounds familiar if you have any experience in object-oriented programming-and I hope you have some experience. Encapsulation is one of the three principles of object-oriented programming. Another term for encapsulation is data hiding. In classical object-oriented programming, which is different from the prototype OOP that JavaScript depends on, data hiding is an inherent part of building a class template.

For example, in C #, the encapsulation of the Animal class-- hidden data-- specific values are associated with Animal objects. That way, if someone decides to change those values, he or he must explicitly do so by initializing an Animal object and setting the value of the object. In JavaScript, we can set values in the global window object at will.

Public class Animal {/ / constructor allows user to set the commonName public animal (string name) {this.commonName = name;} / / making commonName private hides (encapsulates) it in the class private string commonName; / / explicitly exposing the value for reading only public string CommonName get {return this.commonName}}

In JavaScript, modules have been created to simulate this encapsulation behavior, so we don't organize our variables into a global namespace, creating hidden problems that are difficult to find and fix.

Now that you know why, let's see how this can happen.

The expression (IIFE) in which the function is called immediately

It looks as if every time we take a step forward, we have to go the other way. Because to get the JavaScript syntax that allows us to create module patterns, we have to understand an expression syntax called function being called immediately, also called IIFE (IIFE pronounced "iffy").

The most basic IIFE looks like this:

(function () {/ / lines / / of / / code} ())

If you've never seen anything like this, you're a little out of line.

Be called immediately

First of all, the reason why the * part of the name is called immediately is that when the source file containing this particular function is loaded, the code contained in the function will run.

A closer look at IIFE grammar

You can see that the center of this syntax is a function. Take a look at this code block. I've segmented the code and numbered some lines so we can talk about it.

(/ / 1. Function () / 2. {/ / 3. / / one line / line / / code} () / / 4.); / / 5.

First, look at line 2 of the script above. This line usually looks like an anonymous (that is, unnamed) function declaration. Then, 3 through 4 is the subject part of this function. Line 4 ends with a pair of parentheses that tell the JavaScript interpreter to call the function. Eventually, all of this will be wrapped in parentheses (lines 1 and 5) that do not belong to any part, and this pair of parentheses will tell the interpreter to call this external anonymous function, which contains the function we defined.

IIFE can take parameters.

This strange grammar will look even weirder with parameters. It will look like this.

(function (thing1, thing2) {/ / lines / / of / / code} ("in string" 382)

Now, you can see that this function can take two thing1 and thing2 parameters that will be referenced by the internal function. The values passed in are "in string" and 382. 0 in the example.

Now that we understand the IIFE syntax, let's create another code example that we'll run to see how encapsulation works.

(function () {var isDoingWork = false; console.log ("isDoingWork value:" + isDoingWork);} ()); see for yourself

To see how it works, you can do the following steps:

Download the source code for this article.

Open modulePattern3.htm in your browser.

Open the browser's development tools-- F12 (Chrome, IE) or Ctrl-Shift-I (Opera)-- (so you can see the console)

You can see what's shown in the picture like this one below.

When the method is called-this occurs immediately after the code is loaded by the JavaScript interpreter-the function creates an isDoingWork variable and calls console.log () to output the value of the variable on the console.

Now, let's use the console in the development tool to try the steps we tried before:

Enter: isDoingWork and enter

When you do this, you will see that the browser no longer believes that the value isDoingWork has been defined. Even if you try to get this value from the global window object, the browser does not think that the value isDoingWork is defined in this object. The error message you see will look like the one shown in the next picture.

Function is an object: it creates a scope

This is because now you have created the variable isDoingWork in a function-- that is, our anonymous IIFE-- so that the variable can only be accessed through this function. What's interesting is that all functions in Javascript are * * class objects. That simply means that a function is an object that can be accessed through a variable. Or, another way to describe it is that you store a reference to the function and get its variable at some later time.

In our example, our problem is that we don't keep a reference to our anonymous function, so we can never get the value isDoingWork again. This is where we want to improve our next example.

Function is an object: using this

Because each function is an object, each function has a this variable that provides the developer with a reference to the current object. To provide access to our function and its scope from the outside, we can return the this variable-which will provide a reference to the current object.

Then, unless we add this private isDoingWork variable to the function reference (this), we can't reference it either. To do this, we need to make a slight change to the previous example. It will look like this:

Thing = (function () {/ / 1.this.isDoingWork = false; / / 2.console.log ("isDoingWork value:" + isDoingWork); return this; / / 3.} ())

You can see that the line * We have added a new global variable, thing, which contains the value returned from the anonymous function. Skip to the third line from the beginning of the sample code, and you can see that we return the this variable. That means we return a reference to an anonymous function.

We have also added isDoingWork to the this reference in the second line, so we can use the syntax thing.isDoingWork to refer to this value externally.

See for yourself.

To see how it works, you can do the following steps:

Download the sample code for this article.

Open modulePattern4.htm in your browser.

Open browser development tools-- F12 (Chrome, IE) or Ctrl-Shift-I (Opera)-- (so you can see the console)

You will see the value of isDoingWork output to the console, as you saw in the initial example.

Now, however, you have to type thing.isDoingWork to or this value.

Module pattern summary

In this example, the value of the variable is successfully encapsulated, while other JavaScript libraries can explicitly reference the thing object to get the value. It seems unlikely, and this helps us keep the global namespace clean and looks like a better form of code organization. This also makes it easier to maintain our code.

Eventually, we used AngularJS.

Because using module mode is a practice, AngularJS developers build a module system into the library.

Plunker code

First you can get the entire AngularJS example by going to the Plunker (http://plnkr.co/edit/js8rbKpIuAuePzLF2DcP?p=preview-opens in a new window or Tab page).

And we show the code here so that we can talk about it more easily.

First of all, let's look at this HTML.

Angular Module Example

Mc refers to MainCtrl which has been added to the angular app module

Hello {{mc.name}}!

{{a}}

Hello {{sc.name}}

{{a}} Angular instruction: ng-app

What Angular defines and uses is called instructions. These instructions are basically defined by Angular, and the AngularJS compiler (Angular's JavaScript) converts them into something else.

We applied the ng-app directive and defined a name for our Angular application called mainApp.

MainApp is the starting point for the module pattern we will see later.

Introduced scripts: each is a module

Now, notice that three scripts have been introduced into the HTML.

* is a required AngularJS library.

The other two are Angular controllers implemented as modules.

They are implemented as modules to keep the code independent of each other and from this application point of view.

AngularJS: creating score

Looking down, you will see two div that begin with the following code:

This is setting ng-controller for each of the div. Each of these div has its own scope. The name of the * controller is MainCtrl, and the second one is SecondCtrl.

The AngularJS compiler will use these two names to find the corresponding function in the code you provide.

If the AngularJS compiler does not find a function corresponding to these two names, it will throw an error.

MainCtrl.js: controller

Let's see what's in the mainCtrl.js file.

You can click it on the left side of the Plunker page to open it in Plunker.

When you open it, you will see some code that looks familiar. Well, you can at least see that they are all wrapped in an IIFE.

(function () {var app = angular.module (& apos;mainApp', []); app.controller (& apos;MainCtrl', function () {console.log ("in MainCtrl..."); / / vt = virtual this-just shorthand vt = this; vt.name = & apos;MainCtrl'; vt.allThings = ["first", "second", "third"];}) ) ()

That's because we need the code to run when the file mainCtrl.js is loaded.

Now, notice the * * lines of code in this IIFE.

Var app = angular.module (& apos;mainApp', [])

This line of code is how Angular adds a module to its namespace. Here, we have added a module that will be used to showcase our application. This is the application module, and we have named it itmainApp, which is the same as the value specified by ng-app on the HTML page.

We have also created a local variable called app (visible only locally in IIFE) so that we can add a controller again inside this function.

Strange Angular syntax

Please take a closer look at the * line, too. You will notice that we * create the mainApp module, and if it is *, we must provide any dependencies it may need in the form of an array of strings (indicating the name of the dependent library). Here, however, we don't need any dependencies for this simple example. But Angular still needs us to pass in an empty array so that it knows that we are creating a new module instead of trying to load a module that has already been created.

Tip: you will see that we will load the mainApp module in secondCtrl.js, and the array mentioned above will do more.

As soon as we create the mainApp, we need to add our controller to it. These are the controllers that Angular expects us to add to HTML.

Add a controller to the App module

The code to add the controller looks like this:

App.controller (& apos;MainCtrl', function () {console.log ("in MainCtrl..."); / / vt = virtual this-just shorthand vt = this; vt.name = & apos;MainCtrl'; vt.allThings = ["first", "second", "third"];})

To add our controller function, we provide a controller name and a function to the app.controller () function. Here we provide an anonymous function.

So, our controller body code is the following lines:

Console.log ("in MainCtrl..."); / / vt = virtual this-just shorthand vt = this; vt.name = & apos;MainCtrl'; vt.allThings = ["first", "second", "third"]

Here, when our controller is running, it will output a line to the console. Then, we renamed the this variable to vt (for convenience, call it virtual this), and then I added a name attribute and a string array called allThings to it.

Controller and encapsulation

That is the code that runs when the controller is called by Angular. That controller runs when the file is loaded, that is, when the HTML is loaded at first. This means that the controller is loaded into the app module and these properties are added to the controller object (function). Because we want the this variable to add properties, we can get them later, but they are encapsulated, so they can't be changed by everyone at will.

Now, let's jump to where the controller is referenced and used in HTML.

* Div

This is the * * Div that our MainCtrl controller is referenced and used. It looks like this:

Mc refers to MainCtrl which has been added to the angular app module

Hello {{mc.name}}!

{{a}}

This div outputs the following section of our web page, which looks like what is shown in the next picture.

The output is created using the Angular directive

However, it uses a special way to create that output, using two Angular instructions:

{{mc.name}}

Ng-repeat

* instructions are associated with MainCtrl declarations and references on the Div line. We told Angular that we wanted to reference our MainCtrl function (object) under the name mc. That's one of the great abbreviations provided by Angular.

Now, because we have put an attribute on the this object of MainCtrl, we can now refer to those things by mc and the name of the property. We put those things in special double curly braces {{}}, so that the Angular compiler knows that it is runnable code, and you will see that Angular converts it to HTML:

Hello {{mc.name}}!

The following is programmed:

Hello MainCtrl!

After that, we set up a nice no-list and used the ng-repeat instruction to iterate over each line in the output array.

Then Angular falls down the entire allThings array and replaces it with the following HTML

{{a}}

It becomes the following output

1. First

2. Second

3. Third

It's that simple. This is everything about modularization, and our values will never be tampered with by anyone again.

SecondCtrl: it's almost the same thing

Here is the code for SecondCtrl. The code opportunity is the same, except that we get my original app module a little different-not create it * times.

(function () {var app = angular.module (& apos;mainApp'); app.controller (& apos;SecondCtrl', function () {console.log ("in SecondCtrl..."); / / vt = virtual this-just shorthand vt = this; vt.name = & apos;SecondCtrl'; vt.allThings = ["bacon", "lettuce", "tomato"];});})

Take a closer look at the following line:

Var app = angular.module (& apos;mainApp')

The only difference is that we do not provide an array of references.

That's because mainApp already exists, and we just want to add another new module (SecondCtrl) to it.

The above is an example analysis of using modules to organize code in AngularJS. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report