AngularJS入門(mén)開(kāi)發(fā):從核心概念到實(shí)戰(zhàn)案例

在完成AngularJS環(huán)境配置后,入門(mén)開(kāi)發(fā)的核心是掌握“數(shù)據(jù)驅(qū)動(dòng)視圖”的開(kāi)發(fā)思想——通過(guò)模塊、控制器、指令三大核心組件,實(shí)現(xiàn)頁(yè)面與數(shù)據(jù)的聯(lián)動(dòng)。本文不糾結(jié)復(fù)雜理論,而是以“概念講解+實(shí)戰(zhàn)案例”的形式,帶你快速上手AngularJS開(kāi)發(fā),最終能獨(dú)立完成簡(jiǎn)單的交互功能(如表單處理、列表渲染)。

一、先搞懂3個(gè)核心概念:AngularJS的“骨架”

AngularJS的開(kāi)發(fā)邏輯圍繞“模塊管理應(yīng)用、控制器處理數(shù)據(jù)、指令連接視圖”展開(kāi),這三個(gè)概念是所有開(kāi)發(fā)的基礎(chǔ),必須先理解再動(dòng)手。

1. 模塊(Module):應(yīng)用的“容器”

模塊是AngularJS應(yīng)用的最小單位,用于封裝控制器、服務(wù)、過(guò)濾器等功能,避免全局變量污染。每個(gè)應(yīng)用至少需要一個(gè)“根模塊”,通過(guò)ng-app指令掛載到頁(yè)面上。

核心語(yǔ)法:創(chuàng)建模塊

// 語(yǔ)法:angular.module('模塊名', [依賴(lài)的其他模塊])

// 示例:創(chuàng)建名為"myApp"的根模塊,無(wú)依賴(lài)(依賴(lài)數(shù)組為空)

const myApp = angular.module('myApp', []);

關(guān)鍵說(shuō)明:

模塊名必須與頁(yè)面中ng-app="模塊名"的屬性值一致,否則應(yīng)用無(wú)法生效;

依賴(lài)數(shù)組用于引入其他模塊(如angular-route路由模塊),入門(mén)階段可先留空。

2. 控制器(Controller):數(shù)據(jù)的“處理器”

控制器是連接“數(shù)據(jù)”與“視圖”的橋梁,負(fù)責(zé)定義頁(yè)面所需的數(shù)據(jù)($scope)和交互邏輯(如點(diǎn)擊事件、數(shù)據(jù)計(jì)算)。通過(guò)ng-controller指令將控制器與頁(yè)面元素綁定,實(shí)現(xiàn)數(shù)據(jù)渲染。

核心語(yǔ)法:創(chuàng)建控制器

// 基于已創(chuàng)建的"myApp"模塊,添加控制器

myApp.controller('myCtrl', function($scope) {

? // 1. 定義頁(yè)面所需數(shù)據(jù)(掛載到$scope上,視圖可直接訪問(wèn))

? $scope.username = 'AngularJS初學(xué)者';

? $scope.age = 20;

? $scope.hobbies = ['編程', '閱讀', '運(yùn)動(dòng)'];

? // 2. 定義交互邏輯(視圖可通過(guò)指令觸發(fā))

? $scope.increaseAge = function() {

? ? $scope.age += 1; // 修改數(shù)據(jù)后,視圖會(huì)自動(dòng)更新(雙向綁定)

? };

? // 3. 定義數(shù)據(jù)計(jì)算邏輯

? $scope.getHobbyText = function() {

? ? return $scope.hobbies.join('、'); // 將數(shù)組轉(zhuǎn)為字符串,供視圖顯示

? };

});

關(guān)鍵說(shuō)明:

$scope是控制器與視圖的“通信媒介”:控制器中掛載到$scope的數(shù)據(jù)/方法,視圖可直接使用;視圖中修改$scope數(shù)據(jù)(如輸入框),控制器也能實(shí)時(shí)獲??;

控制器名需與頁(yè)面中ng-controller="控制器名"的屬性值一致,綁定后該元素及其子元素可訪問(wèn)控制器中的數(shù)據(jù)。

3. 指令(Directive):視圖的“增強(qiáng)工具”

指令是AngularJS的特色功能,本質(zhì)是“自定義HTML屬性或標(biāo)簽”,用于實(shí)現(xiàn)“數(shù)據(jù)綁定、事件綁定、循環(huán)渲染”等交互。入門(mén)階段需掌握以下5個(gè)高頻指令:

指令作用示例

ng-app掛載根模塊,標(biāo)記AngularJS應(yīng)用范圍<body ng-app="myApp">

ng-controller綁定控制器,讓視圖可訪問(wèn)控制器數(shù)據(jù)<div ng-controller="myCtrl">

ng-model雙向數(shù)據(jù)綁定(輸入框/下拉框等表單元素)<input type="text" ng-model="username">

ng-click綁定點(diǎn)擊事件,觸發(fā)控制器中的方法<button ng-click="increaseAge()">年齡+1</button>

ng-repeat循環(huán)渲染列表(遍歷數(shù)組/對(duì)象)<li ng-repeat="hobby in hobbies">{{ hobby }}</li>

二、實(shí)戰(zhàn)案例1:開(kāi)發(fā)一個(gè)“個(gè)人信息卡片”

結(jié)合上述核心概念,先開(kāi)發(fā)一個(gè)簡(jiǎn)單的“個(gè)人信息卡片”——實(shí)現(xiàn)“數(shù)據(jù)渲染、點(diǎn)擊修改數(shù)據(jù)、循環(huán)顯示列表”功能,理解AngularJS的開(kāi)發(fā)流程。

1. 完整代碼(HTML+JS)

<!DOCTYPE html>

<html lang="zh-CN">

<head>

? ? <meta charset="UTF-8">

? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">

? ? <title>AngularJS實(shí)戰(zhàn) - 個(gè)人信息卡片</title>

? ? <!-- 引入AngularJS(已安裝,直接使用CDN或本地文件) -->

? ? <script src="https://apps.bdimg.com/libs/angular.js/1.8.2/angular.min.js"></script>

? ? <style>

? ? ? ? .card {

? ? ? ? ? ? width: 400px;

? ? ? ? ? ? margin: 50px auto;

? ? ? ? ? ? padding: 20px;

? ? ? ? ? ? border: 1px solid #eee;

? ? ? ? ? ? border-radius: 8px;

? ? ? ? ? ? box-shadow: 0 2px 8px rgba(0,0,0,0.05);

? ? ? ? }

? ? ? ? .card h3 {

? ? ? ? ? ? margin-top: 0;

? ? ? ? ? ? color: #333;

? ? ? ? }

? ? ? ? .info-item {

? ? ? ? ? ? margin: 10px 0;

? ? ? ? ? ? line-height: 1.5;

? ? ? ? }

? ? ? ? .btn {

? ? ? ? ? ? padding: 8px 16px;

? ? ? ? ? ? border: none;

? ? ? ? ? ? background: #4285f4;

? ? ? ? ? ? color: white;

? ? ? ? ? ? border-radius: 4px;

? ? ? ? ? ? cursor: pointer;

? ? ? ? }

? ? ? ? .hobby-list {

? ? ? ? ? ? padding-left: 20px;

? ? ? ? ? ? margin: 5px 0;

? ? ? ? }

? ? </style>

</head>

<!-- 1. 掛載根模塊myApp -->

<body ng-app="myApp">

? ? <!-- 2. 綁定控制器myCtrl,該div內(nèi)可訪問(wèn)控制器數(shù)據(jù) -->

? ? <div class="card" ng-controller="myCtrl">

? ? ? ? <h3>個(gè)人信息卡片</h3>


? ? ? ? <!-- 3. 渲染控制器中的數(shù)據(jù)({{ 數(shù)據(jù)名 }} 是插值表達(dá)式) -->

? ? ? ? <div class="info-item">

? ? ? ? ? ? 姓名:{{ username }}

? ? ? ? ? ? <!-- 4. 雙向綁定:輸入框修改后,username自動(dòng)更新 -->

? ? ? ? ? ? <input type="text" ng-model="username" style="margin-left: 10px; padding: 5px;">

? ? ? ? </div>


? ? ? ? <div class="info-item">

? ? ? ? ? ? 年齡:{{ age }}

? ? ? ? ? ? <!-- 5. 綁定點(diǎn)擊事件:觸發(fā)控制器中的increaseAge方法 -->

zhiq.zhaopin.com/moment/86387543

zhiq.zhaopin.com/moment/86387545

zhiq.zhaopin.com/moment/86387547

zhiq.zhaopin.com/moment/86390891

zhiq.zhaopin.com/moment/86390949

zhiq.zhaopin.com/moment/86390989

zhiq.zhaopin.com/moment/86391003

zhiq.zhaopin.com/moment/86391045

zhiq.zhaopin.com/moment/86391075

zhiq.zhaopin.com/moment/86391146

zhiq.zhaopin.com/moment/86391165

zhiq.zhaopin.com/moment/86391176

zhiq.zhaopin.com/moment/86391214

zhiq.zhaopin.com/moment/86391226

zhiq.zhaopin.com/moment/86391260

zhiq.zhaopin.com/moment/86391274

zhiq.zhaopin.com/moment/86391318

zhiq.zhaopin.com/moment/86391426

zhiq.zhaopin.com/moment/86391570

zhiq.zhaopin.com/moment/86391588

? ? ? ? ? ? <button class="btn" ng-click="increaseAge()" style="margin-left: 10px;">年齡+1</button>

? ? ? ? </div>


? ? ? ? <div class="info-item">

? ? ? ? ? ? 愛(ài)好:

? ? ? ? ? ? <!-- 6. 循環(huán)渲染:遍歷hobbies數(shù)組,生成li列表 -->

? ? ? ? ? ? <ul class="hobby-list">

? ? ? ? ? ? ? ? <li ng-repeat="hobby in hobbies">

? ? ? ? ? ? ? ? ? ? {{ $index + 1 }}. {{ hobby }} <!-- $index是ng-repeat的內(nèi)置變量,代表當(dāng)前索引(從0開(kāi)始) -->

? ? ? ? ? ? ? ? </li>

? ? ? ? ? ? </ul>

? ? ? ? </div>


? ? ? ? <div class="info-item">

? ? ? ? ? ? 愛(ài)好匯總:{{ getHobbyText() }} <!-- 調(diào)用控制器中的方法,渲染返回值 -->

? ? ? ? </div>

? ? </div>

? ? <script>

? ? ? ? // 1. 創(chuàng)建根模塊myApp

? ? ? ? const myApp = angular.module('myApp', []);


? ? ? ? // 2. 給模塊添加控制器myCtrl

? ? ? ? myApp.controller('myCtrl', function($scope) {

? ? ? ? ? ? // 定義初始數(shù)據(jù)

? ? ? ? ? ? $scope.username = '張三';

? ? ? ? ? ? $scope.age = 22;

? ? ? ? ? ? $scope.hobbies = ['打籃球', '寫(xiě)代碼', '看電影'];


? ? ? ? ? ? // 定義點(diǎn)擊事件方法

? ? ? ? ? ? $scope.increaseAge = function() {

? ? ? ? ? ? ? ? $scope.age += 1;

? ? ? ? ? ? };


? ? ? ? ? ? // 定義數(shù)據(jù)處理方法

? ? ? ? ? ? $scope.getHobbyText = function() {

? ? ? ? ? ? ? ? return $scope.hobbies.join('、');

? ? ? ? ? ? };

? ? ? ? });

? ? </script>

</body>

</html>

2. 效果與核心邏輯

打開(kāi)頁(yè)面后,會(huì)自動(dòng)渲染“姓名、年齡、愛(ài)好”數(shù)據(jù);

修改姓名輸入框內(nèi)容,頁(yè)面中“姓名:XXX”會(huì)實(shí)時(shí)同步(ng-model雙向綁定);

點(diǎn)擊“年齡+1”按鈕,年齡數(shù)值會(huì)自動(dòng)加1并更新到頁(yè)面(ng-click觸發(fā)方法,數(shù)據(jù)修改后視圖自動(dòng)更新);

愛(ài)好列表通過(guò)ng-repeat循環(huán)生成,無(wú)需手動(dòng)拼接HTML($index獲取當(dāng)前循環(huán)索引)。

三、實(shí)戰(zhàn)案例2:開(kāi)發(fā)“待辦事項(xiàng)(Todo)列表”

掌握基礎(chǔ)數(shù)據(jù)渲染后,再開(kāi)發(fā)一個(gè)更貼近實(shí)際需求的“待辦事項(xiàng)列表”——實(shí)現(xiàn)“添加待辦、標(biāo)記完成、刪除待辦、統(tǒng)計(jì)數(shù)量”功能,綜合運(yùn)用AngularJS核心能力。

1. 需求拆解

輸入框輸入待辦內(nèi)容,點(diǎn)擊“添加”按鈕新增待辦項(xiàng);

點(diǎn)擊待辦項(xiàng),標(biāo)記為“已完成”(樣式變灰+刪除線(xiàn));

每個(gè)待辦項(xiàng)右側(cè)有“刪除”按鈕,點(diǎn)擊可刪除該待辦;

實(shí)時(shí)統(tǒng)計(jì)“未完成待辦數(shù)量”和“總待辦數(shù)量”。

2. 完整代碼

<!DOCTYPE html>

<html lang="zh-CN">

<head>

? ? <meta charset="UTF-8">

? ? <meta name="viewport" content="width=device-width, initial-scale=1.0">

? ? <title>AngularJS實(shí)戰(zhàn) - 待辦事項(xiàng)列表</title>

? ? <script src="https://apps.bdimg.com/libs/angular.js/1.8.2/angular.min.js"></script>

? ? <style>

? ? ? ? .todo-container {

? ? ? ? ? ? width: 500px;

? ? ? ? ? ? margin: 50px auto;

? ? ? ? ? ? padding: 20px;

? ? ? ? ? ? border: 1px solid #eee;

? ? ? ? ? ? border-radius: 8px;

? ? ? ? }

? ? ? ? .todo-input {

? ? ? ? ? ? display: flex;

? ? ? ? ? ? gap: 10px;

? ? ? ? ? ? margin-bottom: 20px;

? ? ? ? }

? ? ? ? .todo-input input {

? ? ? ? ? ? flex: 1;

? ? ? ? ? ? padding: 8px;

? ? ? ? ? ? border: 1px solid #ddd;

? ? ? ? ? ? border-radius: 4px;

? ? ? ? }

? ? ? ? .todo-item {

? ? ? ? ? ? display: flex;

? ? ? ? ? ? justify-content: space-between;

? ? ? ? ? ? align-items: center;

? ? ? ? ? ? padding: 10px;

? ? ? ? ? ? margin: 8px 0;

? ? ? ? ? ? background: #f9fafb;

? ? ? ? ? ? border-radius: 4px;

? ? ? ? }

? ? ? ? .todo-item.completed {

? ? ? ? ? ? background: #f3f4f6;

? ? ? ? ? ? color: #9ca3af;

? ? ? ? ? ? text-decoration: line-through;

? ? ? ? }

? ? ? ? .delete-btn {

? ? ? ? ? ? border: none;

? ? ? ? ? ? background: #ef4444;

? ? ? ? ? ? color: white;

? ? ? ? ? ? padding: 4px 8px;

? ? ? ? ? ? border-radius: 4px;

? ? ? ? ? ? cursor: pointer;

? ? ? ? ? ? font-size: 12px;

? ? ? ? }

? ? ? ? .todo-count {

? ? ? ? ? ? margin-top: 20px;

? ? ? ? ? ? text-align: right;

? ? ? ? ? ? color: #6b7280;

? ? ? ? }

? ? </style>

</head>

<body ng-app="todoApp">

? ? <div class="todo-container" ng-controller="todoCtrl">

? ? ? ? <h3>待辦事項(xiàng)列表</h3>


? ? ? ? <!-- 添加待辦:輸入框綁定newTodo,點(diǎn)擊按鈕觸發(fā)addTodo -->

? ? ? ? <div class="todo-input">

? ? ? ? ? ? <input type="text"

? ? ? ? ? ? ? ? ? ng-model="newTodo"

? ? ? ? ? ? ? ? ? placeholder="請(qǐng)輸入待辦事項(xiàng)..."

? ? ? ? ? ? ? ? ? ng-keyup="($event.keyCode === 13) && addTodo()"> <!-- 按回車(chē)鍵也能添加 -->

? ? ? ? ? ? <button class="btn" ng-click="addTodo()">添加</button>

? ? ? ? </div>


? ? ? ? <!-- 待辦列表:循環(huán)渲染todos數(shù)組,點(diǎn)擊項(xiàng)觸發(fā)toggleComplete,點(diǎn)擊刪除觸發(fā)deleteTodo -->

? ? ? ? <div class="todo-list">

? ? ? ? ? ? <div class="todo-item"

? ? ? ? ? ? ? ? ng-repeat="todo in todos"

? ? ? ? ? ? ? ? ng-class="{ completed: todo.isCompleted }" <!-- 動(dòng)態(tài)添加completed類(lèi)(已完成時(shí)) -->

? ? ? ? ? ? ? ? ng-click="toggleComplete(todo)">

? ? ? ? ? ? ? ? <span>{{ todo.content }}</span>

? ? ? ? ? ? ? ? <button class="delete-btn" ng-click="deleteTodo($index); $event.stopPropagation()">刪除</button>

? ? ? ? ? ? </div>


? ? ? ? ? ? <!-- 無(wú)待辦時(shí)顯示提示 -->

? ? ? ? ? ? <div ng-if="todos.length === 0" style="text-align: center; color: #9ca3af; padding: 20px;">

? ? ? ? ? ? ? ? 暫無(wú)待辦事項(xiàng),點(diǎn)擊添加吧!

? ? ? ? ? ? </div>

? ? ? ? </div>


? ? ? ? <!-- 統(tǒng)計(jì)待辦數(shù)量:過(guò)濾未完成的待辦(使用AngularJS內(nèi)置過(guò)濾器filter) -->

? ? ? ? <div class="todo-count">

? ? ? ? ? ? 總數(shù)量:{{ todos.length }} | 未完成:{{ todos | filter: { isCompleted: false } | length }}

? ? ? ? </div>

? ? </div>

? ? <script>

? ? ? ? // 1. 創(chuàng)建模塊todoApp

? ? ? ? const todoApp = angular.module('todoApp', []);


? ? ? ? // 2. 創(chuàng)建控制器todoCtrl

? ? ? ? todoApp.controller('todoCtrl', function($scope) {

? ? ? ? ? ? // 初始待辦列表(每個(gè)待辦項(xiàng)包含content內(nèi)容和isCompleted完成狀態(tài))

? ? ? ? ? ? $scope.todos = [

? ? ? ? ? ? ? ? { content: '學(xué)習(xí)AngularJS核心概念', isCompleted: false },

? ? ? ? ? ? ? ? { content: '開(kāi)發(fā)待辦事項(xiàng)列表', isCompleted: true }

? ? ? ? ? ? ];


? ? ? ? ? ? $scope.newTodo = ''; // 綁定輸入框的待辦內(nèi)容


? ? ? ? ? ? // 1. 添加待辦方法

? ? ? ? ? ? $scope.addTodo = function() {

? ? ? ? ? ? ? ? // 校驗(yàn):輸入框不能為空

? ? ? ? ? ? ? ? if (!$scope.newTodo.trim()) return;


? ? ? ? ? ? ? ? // 新增待辦項(xiàng)到數(shù)組

? ? ? ? ? ? ? ? $scope.todos.push({

? ? ? ? ? ? ? ? ? ? content: $scope.newTodo.trim(),

? ? ? ? ? ? ? ? ? ? isCompleted: false

? ? ? ? ? ? ? ? });


? ? ? ? ? ? ? ? // 清空輸入框

? ? ? ? ? ? ? ? $scope.newTodo = '';

? ? ? ? ? ? };


? ? ? ? ? ? // 2. 標(biāo)記待辦完成/未完成方法

? ? ? ? ? ? $scope.toggleComplete = function(todo) {

? ? ? ? ? ? ? ? todo.isCompleted = !todo.isCompleted; // 切換完成狀態(tài)

? ? ? ? ? ? };


? ? ? ? ? ? // 3. 刪除待辦方法(通過(guò)$index獲取當(dāng)前待辦的索引)

? ? ? ? ? ? $scope.deleteTodo = function(index) {

? ? ? ? ? ? ? ? $scope.todos.splice(index, 1); // 從數(shù)組中刪除該待辦

? ? ? ? ? ? };

? ? ? ? });

? ? </script>

</body>

</html>

3. 核心知識(shí)點(diǎn)拓展

動(dòng)態(tài)樣式(ng-class):通過(guò)ng-class="{ 類(lèi)名: 條件 }"實(shí)現(xiàn)“條件滿(mǎn)足時(shí)添加類(lèi)”,如待辦完成時(shí)添加completed類(lèi);

**事件冒泡阻止($$event.stopPropagation())**:刪除按鈕的點(diǎn)擊事件會(huì)觸發(fā)父元素的`ng-click`,需用$$event.stopPropagation()`阻止冒泡;

內(nèi)置過(guò)濾器(filter):todos | filter: { isCompleted: false }表示“過(guò)濾出isCompleted為false的待辦項(xiàng)”,再用| length統(tǒng)計(jì)數(shù)量;

條件渲染(ng-if):ng-if="todos.length === 0"表示“當(dāng)待辦數(shù)組為空時(shí),顯示提示內(nèi)容”(ng-if會(huì)移除/添加DOM元素,不同于ng-show的隱藏)。

四、入門(mén)開(kāi)發(fā)的3個(gè)關(guān)鍵技巧

優(yōu)先用$scope管理數(shù)據(jù):所有需要在視圖中顯示或交互的數(shù)據(jù),都掛載到$scope上,避免使用全局變量;

善用內(nèi)置指令和過(guò)濾器:AngularJS提供大量?jī)?nèi)置指令(如ng-if/ng-show/ng-hide)和過(guò)濾器(如filter/orderBy),減少手動(dòng)JS操作;

調(diào)試用$scope打印:遇到數(shù)據(jù)不更新時(shí),可在控制器中用console.log($scope.數(shù)據(jù)名)查看數(shù)據(jù)是否正確,或在瀏覽器控制臺(tái)輸入angular.element(document.body).scope()獲取當(dāng)前$scope對(duì)象。

五、下一步學(xué)習(xí)方向

完成入門(mén)開(kāi)發(fā)后,可逐步學(xué)習(xí)以下內(nèi)容,提升AngularJS能力:

服務(wù)(Service):用于封裝復(fù)用邏輯(如Ajax請(qǐng)求、數(shù)據(jù)緩存),避免控制器代碼冗余;

過(guò)濾器(Filter):自定義過(guò)濾器,實(shí)現(xiàn)特殊數(shù)據(jù)處理(如日期格式化、金額保留兩位小數(shù));

路由(angular-route):實(shí)現(xiàn)多頁(yè)面切換(如“待辦列表頁(yè)”和“待辦詳情頁(yè)”);

表單驗(yàn)證:使用AngularJS內(nèi)置的表單驗(yàn)證指令(如`ng-required

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容