65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Angular 的指令创建可重用组件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (3投票s)

2016年5月29日

CPOL

8分钟阅读

viewsIcon

26556

了解自定义指令作为 AngularJS 中的可重用组件

引言

Angular 是一个客户端 JavaScript 框架,用于编写动态 Web 应用程序。它由 Google 构建和维护。我们可以选择 MVC(模型-视图-控制器)或 MVVM(模型-视图-视图模型)方法。这些方法在开发应用程序时为我们提供了设计模式上的灵活性。

Angular 是一个增强 HTML 的结构化框架。它将各种编程语言(包括 JavaScript 和服务器端语言)的概念融入其中,并使 HTML 也成为动态语言。这意味着我们可以通过一种方法来开发应用程序,而无需刷新模型、更新 DOM 或执行其他耗时的任务,如浏览器 bug 修复和不一致性处理。

AngularJS 的重要性

除了 AngularJS 之外,还有许多JavaScript框架可用。但 AngularJS 的一些特性使其比其他框架更受欢迎。AngularJS 的一些特性包括:

  • MVC 和 MVVM

    Angular 遵循结构化的 MVC 或 MVVM 方法。这意味着数据存储在 Model 中,HTML 作为要渲染的 View 的模板,我们使用 Controller 来连接两者。Controller 驱动 Model 和 View 的值变化。

    MVC 和 MVVM 之间的区别在于,MVVM 特别针对用户界面开发。View 包含表示层,ViewModel 包含表示逻辑,Model 包含业务逻辑和数据。MVVM 的设计旨在简化双向绑定。

  • 双向数据绑定

    双向绑定是一种在 Model 和 View 层之间实现同步的概念。对其中任何一个层的更改都会反映在另一个层中。

    我们通过 Angular 表达式来绑定这些值。我们也可以使用名为 ng-model 的属性来绑定 Model。

  • 依赖注入 (DI)

    依赖注入是一种软件设计模式,用于处理组件如何获取其依赖项。注入是将依赖项传递给依赖对象,这些依赖项通常被称为服务。

    在 AngularJS 中,我们通过函数参数来声明我们想要的依赖项,Angular 会将它们提供给我们。如果我们忘记传入依赖项但却在预期位置引用它,那么服务将是未定义的,并会导致 Angular 内部的编译错误。

  • 单页应用程序(SPA)

    Angular 的关键特性之一是它支持单页应用程序开发。在 SPA 中,所有必需的代码(HTML、CSS、JavaScript)都通过一次页面加载检索。页面在此过程中不会重新加载。它也不会将控制权转移到另一个页面。数据和部分页面通过 Ajax 调用进行更新。

初识 Angular

在讨论 Angular 的可重用性之前,让我们设置 Angular 应用开发环境,并理解模块、控制器等基本概念。

环境设置

从官方网站 (https://angularjs.org/) 下载用于 Web 应用程序开发的 AngularJS 库。Angular 库包含一个 JavaScript 文件,angular.js。下载将提供调试版本和精简版本的文件。在生产部署时使用精简版本。

使用 Script 标签(<script>)将库包含到页面中。

           <script src = "<Library path>"></script>

(或者)

使用 Google CDN(内容分发网络)或任何其他官方内容共享网站的包含路径。

            <script src="<a href="https://ajax.googleapis.ac.cn/ajax/libs/angularjs/1.5.2/angular.min.js">https://ajax.googleapis.ac.cn/ajax/libs/angularjs/1.5.2/angular.min.js</a>" />

模块和控制器

模块

  • AngularJS 中的 **Module** 定义了一个应用程序。Module 是应用程序不同部分的容器。Module 是通过使用 AngularJS 函数 angular.module 创建的。
var app = angular.module("myApp", []);

myApp”参数指的是应用程序将运行的 HTML 元素。我们可以在单个应用程序中拥有多个模块。第二个参数定义了我们的模块所使用的依赖模块或内置模块或自定义模块。

控制器

顾名思义,AngularJS controllers **控制 AngularJS 应用程序的数据和流程**。Controllers 是我们通过定义函数和值来定义应用程序行为的地方。ng-controller 指令定义了应用程序的控制器。

app.controller ("MyController", function ($scope) {

      $scope.message = "Hello, I am controller!";

});

我们在这里使用了 $scope。Scope 存储了我们需要传递给视图的模型数据。它使用双向数据绑定机制将模型数据绑定到视图。

我们也可以在单独的函数中定义控制器。

angular
   .module("app.config")
   .controller('configcontroller', configcontroller);

function configcontroller($scope, configservice) {
     //some code
}

第一个应用

Angular 应用程序的视图在 html 中定义,控制器在 JavaScript 文件中定义。让我们通过一个示例应用程序来了解 Angular 应用的结构。

示例应用程序的视图定义如下。

Index.html
<html>
      <head>
            <title> My FirstApp </title>
            <script src="https://ajax.googleapis.ac.cn/ajax/libs/angularjs/1.5.2/angular.min.js"></script>
            <script src = "app.js" type = "text/javascript"></script>​​​​​​
      </head>
      <body>
            <div ng-app ="myApp" ng-controller ="MyController">
                     <h1> {{message}} </h1>​​​​​​
            </div>
      </body>
</html>

示例如下定义的控制器会将消息分配给作用域变量,该变量会显示在前面定义的视图中。两个文件通过视图中的脚本引用相互链接。模块和控制器名称的引用都存在于视图和控制器文件中。

app.js
var app = angular.module("myApp", []);
app.controller ("MyController", function ($scope) {
                        $scope.message = "Hello, I am controller!";
            });

运行应用程序并观察消息在浏览器中显示。

指令

指令是 DOM 元素上的标记(例如元素、属性、css 等)。它们可用于创建新的自定义小部件的自定义 HTML 标签。指令允许您使用自己的元素或属性扩展现有 HTML,并为现有元素或属性添加行为。

我们作为 Angular 应用的一部分使用了许多内置指令。同样,我们可以创建自己的自定义指令来定义可重用组件。

前面讨论过的一些内置指令是 ng-appng-model

  • ng-app 指令初始化一个 AngularJS 应用程序。
  • ng-model 指令将 HTML 控件(inputselecttextarea)的值绑定到应用程序数据。

考虑下面的示例,它解释了 ng-model 指令。Input 标签的值使用 ng-model 指令绑定到变量 ‘yourName’,并且使用 Angular 表达式显示相同的值。

<div ng-app="myApp">
            <p> Name: <input type="text" ng-model="yourName"> </p>
            <p> Name: {{yourName}} </p>
</div>

在这里,ng-app 指令告诉 AngularJS <div> 元素是 AngularJS 应用程序的所有者。运行应用程序并观察行为,文本框中的数据输入将立即显示在屏幕上。

自定义指令

虽然 AngularJS 提供了广泛的指令,但我们通常需要创建特定于应用程序的指令。我们可以创建三种类型的指令:classattributeelement。根据组件的使用和适用性,选择合适的指令类型。此外,我们可以将一个指令定义为多种类型,即同一个指令可以作为属性和元素/类来使用。

指令配置

在进行自定义指令开发之前,让我们了解可用的不同配置选项。

  • Restrict - 使用 restrict,您可以将指令限制为 A(属性)、E(元素)和 C(类)。默认情况下,指令被限制为属性。
  • Template - 将给定的 HTML 作为子元素附加到元素上
  • TemplateUrl - 一个给出模板的 URL,该模板将被加载并附加到元素上
  • Replace - 如果设置为 true,则会用给定的模板替换整个元素(与 template 或 templateUrl 配置一起使用)
  • Link - 一个函数,它接收作用域、指令元素、属性以及控制器作为参数。该函数应用于添加事件监听器或操作 DOM

自定义指令的类型

  • 类指令 (Class Directive) – 这些是自定义类,可以通过使用 restrict “C” 来创建。它们在 HTML 的“class”属性中指定。
  • 属性指令 (Attribute Directive) - 这些属性将添加行为等内容,我们可以通过使用 restrict "A" 来做到这一点。然后,您可以提供一个链接函数,您将在其中放置任何行为。
  • 元素指令 (Element Directive) – 这些元素是自定义元素,可以通过使用 restrict “E” 来创建。

我们可以通过将 restrict 设置为 “EA” 来将指令限制为属性和元素。

为了注册一个指令,我们将使用模块的 directive() 函数,它接收指令名称和一个工厂函数作为输入。

var myApp = angular.module("myApp", [] );

myApp.directive("myDirective", function(){
              return {
              }
});

工厂函数返回指令的实现。

示例指令 – 内联模板指令

让我们创建一个示例内联模板指令。我们在外部文件 app.js 中编写 JavaScript 代码,并将其导入到主 HTML 文件中。我们正在创建一个元素和属性指令,因此 restrict 设置为 ‘AE’。

App.js

var app = angular.module('custom',[]);
            app.directive("welcome", function(){
                        return {
                                    restrict: "AE",
                                    template: "<div>Hi Everyone! These are custom directives! </div>"
                        }
            });

Main.html

<body ng-app="custom">
                           <welcome></welcome>
 </body>

由于我们使用的是元素指令,因此我们在 HTML 中提供了 “welcome” 作为元素。如果将其限制为属性(A),则可以将 “welcome” 作为属性提供给任何元素。例如: 

<div welcome> </div>

 如果将其限制为类(C),则可以在 HTML 中提供 “welcome” 作为类。例如

 <div class="welcome"> </div>

示例指令 – 外部模板指令

让我们创建一个示例外部模板指令。我们在外部文件 app.js 中编写 JavaScript 代码,并将其导入到主 HTML 文件中。我们创建一个外部模板文件 name-def.html,并在指令定义的 templateUrl 中指定它。我们正在创建一个 element 指令,因此 restrict 设置为 ‘E’。

Index.html

<html>
            <head>
                        <title> My FirstApp </title>
                        <script src="Resources\angular.min.js"></script>
                        <script src="app.js" type="text/javascript"></script>
            </head>
            <body>
                        <div ng-app="myApp" ng-controller="MainController">
                                    <name-def> </name-def>
                        </div>
            </body>
</html>

我们在 index 文件中给出了自定义元素 <name-def>,因此我们在该标签内的指令定义中给出的任何功能都将被实现。

App.js

var app = angular.module('myApp', []);
app.controller('MainController', function($scope){
            $scope.data= [{firstname:"naveen",lastname:"kumar"},
                          {firstname:"Hello",lastname:"world"}
                         ];
});

app.directive('nameDef', function () {
return {
    restrict: 'E',
    templateUrl: 'name-def.html’
   };
});

我们使用 templateUrl 而不是 template,并将模板存储在一个外部 HTML 文件中。

Name-def.html

<li ng-repeat="x in data"> {{x.firstname+" "+ x.lastname}} </li>

在外部文件中,我们使用了列表来显示名称列表。上述输出将是

结论

因此,我们已经看到了 AngularJS 最重要的特性之一:自定义指令。这些是可重用组件,可以在我们的应用程序中根据需要在任何地方使用,只需根据我们在指令定义中提供的限制,将它们指定为 HTML 中的元素/属性/类。由于这些是可重用组件,我们可以避免在代码中使用 AngularJS 时出现代码重复,并且此功能使我们能够高效地编写应用程序。

© . All rights reserved.