关于Angular1中视图与页面DOM

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>
 

转载于:https://my.oschina.net/u/924064/blog/901397

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值