---恢复内容开始---
angular最初进入前端开发人员视野的时候,给人以不可磨灭的印象之一就是它的双向数据绑定的实现。本篇章会先介绍如何使用此功能,然后在深入解释它的双向绑定的机制是如何实现的。
angular中的data-binding指的是模型models和视图views之间的自动同步。angular实现双向绑定后,会让你觉得数据模型是页面中数据唯一的真实来源。当model改变后,视图反映改变,反之亦然。通俗的说,所谓的双向数据绑定,无非就是从界面的操作能实时反映到数据,数据的变更能实时展现到界面。据各最简单的例子:
<div ng-controller="CounterCtrl"> <span ng-bind="counter"></span> <button ng-click="counter++">increase</button> </div> function CounterCtrl($scope) { $scope.counter = 1; }
上面的例子很简单,每当点击一次按钮,界面上的数据就加1。
但是,新手很可能会碰到下面这样的问题。
var app = angular.module("test", []); app.directive("myclick", function() { return function (scope, element, attr) { element.on("click", function() { scope.counter++; }); }; }); app.controller("CounterCtrl", function($scope) { $scope.counter = 0; }); <body ng-app="test"> <div ng-controller="CounterCtrl"> <button myclick>increase</button> <span ng-bind="counter"></span> </div> </body>
上面的例子也很简单:想要实现的事:点击按钮时,span元素中counter加1。但是实际上,视图上并不会这样。然而model中counter确实增加了。也就是说,并没有实现angular所说的数据双向绑定。测试请访问:http://plnkr.co/edit/?p=preview
但是如果在scope.counter++;后面加上scope.$digest();后又没问题了,而第一个例子中并没有使用$digest函数,如果使用了反而报错。这是怎么回事?不妨先看看下面怎么使用原生javascript来实现的。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>two-way binding</title>
</head>
<body onload="init()">
<button ng-click="inc">
increase 1
</button>
<button ng-click="inc2">
increase 2
</button>
<span style="color:red" ng-bind="counter"></span>
<span style="color:blue" ng-bind="counter"></span>
<span style="color:green" ng-bind="counter"></span>
<script type="text/javascript">
/* 数据模型区开始 */
var counter = 0;
function inc() {
counter++;
}
function inc2() {
counter+=2;
}
/* 数据模型区结束 */
/* 绑定关系区开始 */
function init() {
bind();
}
function bind() {
var list = document.querySelectorAll("[ng-click]");
for (var i=0; i<list.length; i++) {
list[i].onclick = (function(index) {
return function() {
window[list[index].getAttribute("ng-click")]();
apply();
};
})(i);
}
}
function apply() {
var list = document.querySelectorAll("[ng-bind='counter']");
for (var