# 一、Angular.js 入门

## 在网页中包含 Angular.js 库代码

### 问题

您希望在网页上使用 Angular.js。

### 解

为了启动并运行您的第一个 Angular.js 应用程序，您需要通过`script`标记包含 Angular JavaScript 文件，并使用`ng-app`指令:

```js
    <html>
    <head>
    <script src="http://ajax.googleapis.com/ajax/libs/ angularjs/1.0.4/angular.js">
    </script>
    </head>
    <body ng-app>
    <p>This is your first angular expression: {{ 1 + 2 }}</p>
    </body>
    </html>

```

你可以在 [GitHub](http://github.com/fdietz/recipes-with-angular-js-examples/tree/master/chapter1/recipe1) 上查看一个完整的例子。

### 讨论

添加`ng-app`指令让 Angular 施展魔法。表达式`{{ 1 + 2 }}`由 Angular 求值，结果`3`被渲染。请注意，移除`ng-app`将导致浏览器按原样呈现表达式，而不是对其求值。玩弄表情！例如，您可以连接字符串并反转或组合布尔值。

为了简洁起见，我们将跳过以下食谱中的样板代码。

## 将文本输入绑定到表达式

### 问题

您希望用户输入用于 HTML 页面的另一部分。

### 解

使用 Angular 的`ng-model`指令将文本输入绑定到表达式:

```js
    Enter your name: <input type="text" ng-model="name"></input>
    <p>Hello {{name}}!</p>

```

你可以在 [GitHub](https://github.com/fdietz/recipes-with-angular-js-examples/tree/master/chapter1/recipe2) 上找到完整的例子。

### 讨论

为`ng-model`属性指定“名称”并在表达式中使用名称变量将自动保持两者同步。在文本输入中键入将自动在下面的段落元素中反映这些变化。

考虑如何使用传统的 jQuery 实现这一点:

```js
    <html>
    <head>
    <script src="http://code.jquery.com/jquery.min.js"></script>
    </head>
    <body>
    Enter your name: <input type="text"></input>
    <p id="name"></p>

    <script>
    $(document).ready(function() {
    $("input").keypress(function() {
    $("#name").text($(this).val());
    });
    });
    </script>

    </body>
    </html>

```

在文档就绪时，我们绑定到文本输入中的 keypress 事件，并在回调函数中替换段落中的文本。使用 jQuery，您需要处理文档就绪回调、元素选择、事件绑定和上下文。相当多的概念需要消化，代码行需要维护！

## 使用控制器响应点击事件

### 问题

您希望在按钮点击时隐藏一个 HTML 元素。

### 解

将`ng-hide`指令与控制器结合使用，改变按钮点击时的可见性状态:

```js
    <html>
    <head>
    <script src="js/angular.js"></script>
    <script src="js/app.js"></script>
    <link rel="stylesheet" href="css/bootstrap.css">
    </head>
    <body ng-app>
    <div ng-controller="MyCtrl">
    <button ng-click="toggle()">Toggle</button>
    <p ng-show="visible">Hello World!</p>
    </div>
    </body>
    </html>

```

`js/app.js`中的控制器:

```js
    function MyCtrl($scope) {
    $scope.visible = true;

    $scope.toggle = function() {
    $scope.visible = !$scope.visible;
    };
    }

```

你可以在 [GitHub](https://github.com/fdietz/recipes-with-angular-js-examples/tree/master/chapter1/recipe3) 上找到完整的例子。

切换按钮时，“你好世界”段落将改变其可见性。

### 讨论

使用`ng-controller`指令，我们将`div`元素，包括其子元素，绑定到`MyCtrl`控制器的上下文。`ng-click`指令将在按钮点击时调用我们控制器的`toggle()`功能。请注意，`ng-show`指令绑定到`visible`范围变量，并将相应地切换段落的可见性。

控制器实现默认`visible`属性为真，并在`toggle`功能中切换其布尔状态。`visible`变量和`toggle`函数都是在`$scope`服务上定义的，该服务通过依赖注入自动传递给所有控制器函数。

下一章将详细介绍 Angular 中控制器的所有细节。现在，让我们快速讨论 Angular 使用的模型-视图-视图模型(MVVM)模式。在 MVVM 模式中，模型是普通的 JavaScript，视图是 HTML 模板，视图模型是模板和模型之间的粘合剂。视图模型使 Angular 的双向绑定成为可能，其中模型或模板中的更改会自动同步。

在我们的例子中，`visible`属性是模型，但是当例如从后端服务检索数据时，它当然会复杂得多。控制器用于定义表示视图模型的范围。它通过绑定作用域变量`visible`和函数`toggle()`来与 HTML 模板交互。

## 使用过滤器转换表达式输出

### 问题

当向用户呈现数据时，您可能需要将数据转换为更加用户友好的格式。在我们的例子中，我们希望将表达式中上一个配方的`name`值大写。

### 解

使用`uppercase`角度滤镜:

```js
    Enter your name: <input type="text" ng-model="name"></input>
    <p>Hello {{name | uppercase }}!</p>

```

你可以在 [GitHub](https://github.com/fdietz/recipes-with-angular-js-examples/tree/master/chapter1/recipe4) 上找到完整的例子。

### 讨论

Angular 使用`|`(管道)字符将过滤器与表达式中的变量组合在一起。计算表达式时，名称变量被传递给大写筛选器。这类似于使用 Unix bash 管道符号，其中一个输入可以被另一个程序转换。还有，试试`lowercase`滤镜！

## 使用指令创建自定义 HTML 元素

### 问题

您希望呈现一个 HTML 片段，但有条件地隐藏它。

### 解

创建一个自定义指令来呈现你好世界片段:

```js
    <body ng-app="MyApp">
    <label for="checkbox">
    <input id="checkbox" type="checkbox" ng-model="visible">Toggle me
    </label>
    <div show="visible">
    <p>Hello World</p>
    </div>
    </body>

```

`show`属性是我们的指令，实现如下:

```js
    var app = angular.module("MyApp", []);

    app.directive("show", function() {
    return {
    link: function(scope, element, attributes) {
    scope.$watch(attributes.show, function(value){
    element.css('display', value ? '' : 'none');
    });
    }
    };
    });

```

如果复选框被选中，浏览器将只显示“你好世界”段落，否则将隐藏它。

你可以在 [GitHub](https://github.com/fdietz/recipes-with-angular-js-examples/tree/master/chapter1/recipe5) 上找到完整的例子。

### 讨论

让我们暂时忽略`app`模块的创建，并在后面的章节中更深入地研究它。在我们的示例中，它只是创建指令的手段。注意`show`字符串是指令的名称，对应于模板中使用的`show` HTML 属性。

指令实现返回定义指令行为的`link`函数。它通过了`scope`、超文本标记语言`element,`和超文本标记语言`attributes`。由于我们将`visible`变量作为属性传递给了我们的`show`指令，我们可以通过`attributes.show`直接访问它。但是由于我们想要自动响应`visible`变量的变化，所以我们必须使用`$watch`服务，每当值发生变化时，它都会为我们提供一个函数回调。在这个回调中，我们将 CSS `display`属性更改为空白或`none`来隐藏 HTML 元素。

这只是对指令能实现什么的一瞥；后面有一整章专门介绍他们，这一章要详细得多。