您的位置:首页 > Web前端 > AngularJS

关于Angular1中视图与页面DOM

2017-05-16 00:00 176 查看
AngularJS通过扩展HTML添加元素,属性,class以及特定注释来完成工作。
AngularJS 动态编译一个页面文档来定位和处理这些扩展内容并创建应用。我们可以使用内建的对JavaScript支持来自定义应用程序的一些行为
并定义自己的Html扩展。

AngularJS的编译是指在页面加载到浏览器后,使用DOM API和JavaScript来添加或者移除元素,创建事件处理器等。
在AngularJS的开发过程中不需要编译,只需要修改html或者JavaScript文件后重新加载到浏览器。

AngularJS对HTML最重要的扩展元素是ng-app属性,它指示html元素包含一个需要被AngularJS编译的模块。
当我们只用AngularJS技术时,我们可以将其添加到页面文档元素的html元素中,如果我们需要跟其它技术配合使用,最好将其放入其它子元素中,
来缩小Angularjs的负责边界。

Creating Data Model:
我们需要将应用程序分为三个部分:数据 model,数据操作逻辑 controller 和 数据显示逻辑 view。

处理数据获取和排序的逻辑应该放在model中,处理数据格式和显示控制的应该放到view中。
controller则是坐落在这两者之间,用于连接这两者,负责用户交互,更新model中的数据,向view提供数据。

var model = {
user: "Adam",
items: [{ action: "Buy Flowers", done: false },
{ action: "Get Shoes", done: false },
{ action: "Collect Tickets", done: true },
{ action: "Call Joe", done: false }]
};

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

todoApp.controller("ToDoCtrl", function ($scope) {
$scope.todo = model;
});

model的主要任务是为view提供它需要的数据,但是我们并不希望view访问所有的model的数据,这时候我们就用controller来显式的选择部分可用数据给view
,这就是scope。

Controller函数的参数$scope,在一个AngularJS应用程序中以$开头的变量表示AngularJS提供的内建内容。一般指内建的服务,它们都是自包含的组件,来为Controller提供
内容。$scope就是用来为view提供数据和函数的对象。我们只需要把要提供给view的内容,添加到$scope容器中即可:$scope.todo = model;

我们还需要在HTML页面文档结构中指定一块区域让controller负责控制。这就是ng-controller属性的功能了。

View负责将Controller提供的数据和HTML元素组合产生需要在浏览器中显示的内容。它用到著名的数据绑定技术。
显示controller提供的model, {{model}}
<tr ng-repeat="item in todo.items">
<td>{{item.action}}</td>
<td>{{item.done}}</td>
</tr>

AngularJS在编译HTML页面文档时,发现<body ng-controller="ToDoCtrl">的ng-controller="ToDoCtrl"属性,会调用ToDoCtrl构造函数来设置一个用于
创建view的scope,然后在遇见数据绑定表达式{{}}时,就去查找$scope对象内部同名的属性和函数,将结果插入到该位置。这个过程就是data binding或者model binding。

数据绑定的表达式可以是任意的合法JavaScript语句,也就是说我们可以通过编写javascript代码来生成新的model数据。
我们不推荐使用复杂的业务逻辑作为绑定表达式,而只是在简单的数据绑定时使用。
复杂逻辑则可以放到controller里定义封装。

关于指令Directives:
表达式也可以用于指令,来告诉AngularJS我们想如何处理内容。
ng-repeat属性的内容是 <name> in <collection>,ng-repeat指令是将集合中每个元素都赋予变量 name。

单向绑定用于在模板中发布一个model数据。
双向绑定则可以将model发布到模板同时跟踪模板中数据的变化反馈给model。
<td><input type="checkbox" ng-model="item.done" /></td>
<td>{{item.done}}</td>

这里的ng-model属性就是告诉AngularJS在input元素和done属性之间建立双向绑定。

Controller定义scope的行为,这些行为做用于model的数据上来实现业务逻辑。
这些行为主要是用于支持view显示model提供的数据给用户,将用户对数据的修改反应到model中。
var model = {
user: "Adam",
items: [{ action: "Buy Flowers", done: false },
{ action: "Get Shoes", done: false },
{ action: "Collect Tickets", done: true },
{ action: "Call Joe", done: false }]
};

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

todoApp.controller("ToDoCtrl", function ($scope) {
$scope.todo = model;
$scope.incompleteCount = function () {
var count = 0;
angular.forEach($scope.todo.items, function (item) {
if (!item.done) { count++ }
});
return count;
}
});

贯穿于整个Angularjs开发中的一个主题就是 如何自然的将HTML,CSS和JavaScript的底层特征用于应用程序开发。
因为行为是通过javascript函数定义的,我们可以在同一个controller中定义基于其它行为定义的行为函数。

todoApp.controller("ToDoCtrl", function ($scope) {
$scope.todo = model;
$scope.incompleteCount = function () {
var count = 0;
angular.forEach($scope.todo.items, function (item) {
if (!item.done) { count++ }
});
return count;
}

$scope.warningLevel = function () {
return $scope.incompleteCount() < 3 ? "label-success" : "label-warning";
}
});

我们可以自由的组合指令和行为定义函数来达到想要的效果。
<span class="label" ng-class="warningLevel()" ng-hide="incompleteCount() == 0">

回应用户交互:
$scope定义的行为函数跟指令的结合来回应用户操作。
todoApp.controller("ToDoCtrl", function ($scope) {
$scope.todo = model;
$scope.incompleteCount = function () {
var count = 0;
angular.forEach($scope.todo.items, function (item) {
if (!item.done) { count++ }
});
return count;
}

$scope.warningLevel = function () {
return $scope.incompleteCount() < 3 ? "label-success" : "label-warning";
}
$scope.addNewItem = function (actionText) {
$scope.todo.items.push({ action: actionText, done: false });
}
});

这里使用了动态创建model:actionText。

Model数据的过滤和排序 chp 14
view中页面显示的过滤完全可以通过定义Scope上的行为函数来完成,但是filter更为通用,可以跨越整个应用程序重用。

<tbody>
<tr ng-repeat="item in todo.items | filter:{done: false} | orderBy:'action'">
<td>{{item.action}}</td>
<td><input type="checkbox" ng-model="item.done" /></td>
</tr>
</tbody>

默认情况下,AngularJS会将没有被单引号包裹的字符都当作定义在$scope上的属性看待。

自定义过滤器:定义一个filter工厂,返回一个用于过滤一个数据对象集合的函数。
使用filter方法需要传入一个返回一个函数的函数,返回的函数需要能够返回一个过滤后的数据集。
下面定义一个名为checkedItems的工厂函数,该工厂函数能够返回一个过滤函数,该过滤函数获取输入后,最终返回一个过滤后的结果集。
var model = {
user: "Adam",
items: [{ action: "Buy Flowers", done: false },
{ action: "Get Shoes", done: false },
{ action: "Collect Tickets", done: true },
{ action: "Call Joe", done: false }],
};
var todoApp = angular.module("todoApp", []);
todoApp.filter("checkedItems", function () {
return function (items, showComplete) {
var resultArr = [];
angular.forEach(items, function (item) {
if (item.done == false || showComplete == true) {
resultArr.push(item);
}
});
return resultArr;
}
});
todoApp.controller("ToDoCtrl", function ($scope) {
$scope.todo = model;
// ...statements omitted for brevity...
});

通过Ajax获取数据:
todo.json
[{ "action": "Buy Flowers", "done": false },
{ "action": "Get Shoes", "done": false },
{ "action": "Collect Tickets", "done": true },
{ "action": "Call Joe", "done": false }]

<script>
var model = {
user:"Adam"
};

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

todoApp.run(function($http){
$http.get("todo.json").success(function(data){
model.items = data;
});
});

todoApp.filter("checkItems", function(){
return function (items,showComplete){
var resultArr = [];
angular.forEach(items,function(item){
if(item.done == false || showComplete == true){
resultArr.push(item);
}
});
return resultArr;
}
});

todoApp.controller("ToDoCtrl",function($scope){
$scope.todo = model;

$scope.incompleteCount = function(){
var count = 0;
angular.forEach($scope.todo.items, function(item){
if(!item.done){ count++ }
});
return count;
}

$scope.warningLevel = function(){
return $scope.incompleteCount()<3 ? "label-success" : "label-warning";
}

$scope.addNewItem = function(actionText){
$scope.todo.items.push({ action:actionText, done:false});
}
});
</script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: