学习AngularJS -- 从新手到专家之路(三)
发布在用Angular开发web应用2013年12月1日view:13061
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

enter image description here

3.数据绑定

我们可以将一个输入字段绑定到person.name属性来让我们的应用变得更加有趣。这一步设置了一个从输入字段到页面的双向绑定。

enter image description here

在这里的双向指的是如果视图中的值发生了改变,那么模型也会发现这些改变,同样如果模型中的值改变了,那么视图也会发现改变。AngularJS会自动为你设置。我们将在后面的内容中深入探讨digest_loop,如果你对它是怎么实现感到好奇的话。

为了设置双向绑定,我们在输入字段中使用ng-model指令,如下所示:

<div ng-controller="MyController">
  <input type='text' ng-model="person.name" palceholder="Enter your name" />
  <h1>Hello {{ person.name }}</h5>
</div>

现在我们已经有了一个双向数据绑定(很简单对吧)。

当你在输入框中输入时,你会看到下面的名字自动改变了。这个改变意味着我们的数据绑定在单方向上成功了,从视图到模型。

我们也可以在(客户端)后端改变模型然后看看它是否能在前端反映出来。

为了说明从后端到前端的数据绑定,我们在MyController模型中创建一个时钟函数,它将更新$scope中的一个值。在这个例子中,我们将创建一个时钟,它每秒钟滴答一声(正如一般的时钟那样)并改变时钟变量中的数据:

app.controller('MyController', function($scope) {
  $scope.person = { name: "Ari Lerner" };
  var updateClock = function() {
    $scope.clock = new Date();
  };
  var timer = setInterval(function() {
    $scope.$apply(updateClock);
  }, 1000);
  updateClock();
});     

正如你所见,当我们在模型中改变了时钟变量时,视图也自动更新来反映变化。

我们可以将clock变量绑定在视图中,只需要将它简单的包裹在{{}}中即可:

<div ng-controller="MyController">
  <h5>{{ clock }}</h5> 
</div>   

交互

注意奥我们将数据绑定到了上面的输入字段中。我们并不需要将数据绑定限制在数据上。我们也可以在$scope中调用函数(正如前面提到的那样)。

wile绑定按钮或链接(或者任意DOM元素),我们将使用另一个内建指令,ng-click。ng-click指令将点击事件绑定到了方法(mousedown浏览器事件),绑定到DOM元素(例如,当浏览器在DOM元素上触发一个点击事件时,该方法被调用)。和前面的例子李四,绑定如下所示:

<div ng-controller="DemoController">
  <h4>The simplest adding machine ever</h4>
  <button ng-click="add(1)" class="button">Add</button>
  <button ng-click="subtract(1)" class="button">Subtract</button>
  <h4>Current count: {{ counter }}</h4>
</div>    

所有的按钮和链接都将绑定到了$scope中的一个动作上,因此当它们被按下(点击)时,Angular将会调用方法。注意到当我们告诉Angular去调用什么方法时,我们将它连同括号放在一个字符串中。

现在,我们在DemoController中创建一个动作:

app.controller('DemoController',function($scope){
    $scope.counter = 0;
    $scope.add = function(amount) {$scopr.counter + = amount;};
    $scope.substract = function(amount) {$scope.counter -= amount; }; 
});   

我们的应用中干的数据绑定和AJAX

交互

正如我们在全面的例子中看到的,我们使用学到的数据绑定技术将一个按钮绑定到视图中。在这个例子中,我们将按钮绑定到play()动作并且将PLayerController的play方法绑定到了play按钮上(对于stop按钮以及stop方法也是同样的道理)。

AJAX

在上一篇文章中,我们使用了一个本地的音频文件;然而,这样做只能获取一个静态的NPR文件按而不是一个直播的NPR。在我们的NPR应用总,我们将使用$http来产生我们需要播放的最新列表。

Angular支持AJAX(或者异步JavaScript和XML)。这使得我们可以向一个或多个服务器发送请求,这对于像我们正在创建的需要获取数据的客户端应用来说是非常重要的。

AngularJS通过一个$http来进行AJAX。

所有的AngularJS核心服务都有$前缀。我们在之前看到过$scope服务。

$http服务使用非常灵活,它让我们可以用多种方式来进行AJAX。为了简单i,我们在这里只讨论最简单的方法。我们将在后面的章节中深入的讨论$http服务。

在我们讨论更多细节之前,我们先使用$http来发出一个请求:

$http({
  method: 'JSONP',
  url: 'http://api.openbeerdatabase.com/v1/beers.json?callback=JSON_CALLBACK'
}).success(function(data, status, headers, config) {
  // data contains the response
  // status is the HTTP status
  // headers is the header getter function
  // config is the object that was used to create the HTTP request
}).error(function(data, status, headers, config) {
});  

$http服务是一个AngularJS的核心服务,它帮助我们通过XMLHttpRequeat对象或者JSONP于远端服务器进行交流。

注意到AngularJS将会小心处理一个JSONP请求如果你在后面追加了EXACT字符串:callback=JSON_CALLBACK,正如前面提到的。AngularJS会把JSON_CALLBACK替换成合适的它为你生成的合适的回调函数。

$http服务是一个函数,它接收一个配置对象,配置对象定义了HTTP请求的构造,它将返回一个拥有两个方法success以及error的promise。

为了得到一个可用的音频列表,我们现在对NPR的API发送一个请求。首先,我们需要在NPR注册得到一个API key。登录网站http://www.npr.org/templates/reg/ 进行注册。

时刻关注你的API key。我们将马上使用它。现在,我们将来设置我么你的PlayerController来调用$http服务获取列表。

正如前面所做的,我们通过$http服务来发送一个请求,这次可以获取所有列表。当控制器实例化时我们想要这项服务开始运行,因此我们可以简单的将则个方法放在控制器函数中(当控制器被创建时它就开始运行),如下所示:

var apiKey = 'YOUR_KEY',
    nprUrl = 'http://api.npr.org/query?id=61&fields=relatedLink,title,byline,text,audio,image,pullQuote,all&output=JSON';

app.controller('PlayerController', function($scope, $http) {
  // Hidden our previous section's content
  // construct our http request
  $http({
    method: 'JSONP',
    url: nprUrl + '&apiKey=' + apiKey + '&callback=JSON_CALLBACK'
  }).success(function(data, status) {
    // Now we have a list of the stories (data.list.story)
    // in the data object that the NPR API 
    // returns in JSON that looks like:
    // data: { "list": {
    //   "title": ...
    //   "story": [
    //     { "id": ...
    //       "title": ...
  }).error(function(data, status) {
    // Some error occurred
  });
});     

现在我们已经在success函数的data中获取的列表,我们可以通过在success回调函数中简单的将列表储存在$scope中来达到绑定的目的:

// from above
}).success(function(data, status) {
  // Store the list of stories on the scope
  // from the NPR API response object (described above)
  $scope.programs = data.list.story;
}).error(function(data, status) {
  // Some error occurred

现在,正如前面的例子遗言给我么可以在视图中引用programs来引用数据。注意到使用AngularJS的好处之一是放promise被解析时他会自动的在视图中生成promis。

<div ng-controller="PlayerController">
  {{ programs }}
</div>     

在下一节中,我们将讨论如何使用内建指令在视图中显示数据。


本系列文章译自 AngularJS - from beginner to expert in 7 steps series,原文地址http://www.ng-newsletter.com/posts/beginner2expert-data-binding.html。转载请注明出处。

如果你觉得本文对你有帮助,请点击下面的链接为我提供赞助。

评论
发表评论
4年前

谁能告诉我双向数据绑定的原理

4年前
赞了此文章!
4年前
添加了一枚【评注】:软件
5年前

翻译的不错,多谢楼主。有些错别字能纠正一下就更好了。

5年前

文章就是第一段代码,如果没有js控制代码,会出现没有定义的错误,去掉ng-controller=”mycontroller”吧。Error: [ng:areq] Argument ‘DemoController’ is not a function, got undefined

5年前

@嘿-sb 一样的道理:

 <div ng-app="myapp" ng-controller="mycontroller">
<h1>Number:{{number}}</h1>
<input ng-model="interval" type='number'/>
<br/>
<button ng-click="add()">add{{interval}}</button>
<button ng-click="minus()">minus{{interval}}</button>
<script type="text/javascript">
    angular.module("myapp",[]).controller('mycontroller', ['$scope', function ($scope) {
            $scope.number = 1;
            $scope.add = function(){
                $scope.number += $scope.interval;
            }       
            $scope.minus = function(){
                $scope.number -= $scope.interval;
            }
    }])
</script>

5年前

@张小俊128 谢谢回复。不过我的意思是,我想加多少减多少这个数可以自己填,add({{ num }})这样子的。

5年前

@嘿-sb 你需要的代码应该是这样:

     <div ng-app="myapp" ng-controller="mycontroller">
<h1>Number:{{number}}</h1>
<input ng-model="number" type='number'/>
<br/>
<button ng-click="add()">add</button>
<button ng-click="minus()">minus</button>
<script type="text/javascript">
    angular.module("myapp",[]).controller('mycontroller', ['$scope', function ($scope) {
            $scope.add = function(){
                $scope.number +=1;
            }       
            $scope.minus = function(){
                $scope.number -=1;
            }
    }])
</script>

希望对你有帮助

5年前

不好意思啊。css里面把评论display:inline了。

5年前

lz你好,先谢谢你的翻译。有个问题想请教一下你,关于数据绑定调用函数那一段,我想自己定义函数的参数,要怎么做才行呢?下面是我的代码,但是不能实现。

app.controller('jjCtrl', function($scope) {
    $scope.shu = 1;
    $scope.jishu = 1;
    $scope.jia = function(jishu) {
        $scope.shu += jishu;
    };
    $scope.jian = function(jishu) {
        $scope.shu -= jishu;
    };
});
<div ng-controller="jjCtrl">
    <h1>{{ shu }}</h1>
    <p><input type="number" ng-model="jishu"></p>
    <button ng-click="jia({{jishu}})">加{{jishu}}</button>
    <button ng-click="jian({{jishu}})">减{{jishu}}</button>
</div>
WRITTEN BY
张小俊128
Intern in Baidu mobile search department。认真工作,努力钻研,期待未来更多可能。
TA的新浪微博
PUBLISHED IN
用Angular开发web应用

讲述Angular开发框架的基础知识,帮助读者快速学习并深入理解Angular的开发理念和具体应用方式

我的收藏