• angularjs入门学习【应用剖析中篇】


       在上一节讲完了关于应用开发中如数据绑定,加入样式一类的基础操作后,接下来,将在应用中,与控制其有关的一些事件。。。


    一、UI和控制器的分离

    我们须要明白控制器在应用中的三个作用:

    【1】在应用模型中设置初始状态

    【2】通过$scope对象向视图(UI模版)暴露函数和模型

    【3】监视模型发生变化的其它部分并做出对应的动作


    二、公布scope中的数据模型

     传递给控制器的$scope对象是一种用来向视图暴露模型数据的机制。在我们构建的应用中可能有其它数据,可是通过scope传递这些属性时,angular仅仅考虑模型部分。

     在之前的荔枝中,我们常常看到$scope构建的数据实例,而这一过程是在控制器中完毕,在这里,我们也能够通过一些间接的方法从模版建立模型。


    1.使用表达式:因为表达式在可它们关联的控制器中运行,所以在表达式中设置属性和控制器中设置属性是一致的。即能够例如以下这么做

    <button ng-click='count=3'>Set count to three</button>

    其等同于

    <div ng-controller='CountController'>
    <button ng-click='setCount()'>Set count to three</button>
    </div>

    控制器定义

    function CountController($scope) {
    $scope.setCount = function() {
    $scope.count=3;
    }
    }

    2.通过ng-model进行一个数据绑定


    三、用$watch观察模型变化

    $watch(watchFn, watchAction, deepWatch)
    该函数每一个參数具体内容

    watchFn:这个參数是angualr表达式字符串或返回监控模型的当前值的函数,该表达式会被运行多次

    watchAction:这是一个函数或者表达式,当watchFn变化时将调用他们,函数形式而言,它有watchFn的新旧值,及一个$scope引用,函数前面function(newValue,oldValue,scope)

    deepWatch:这是一个可选的布尔參数,假设设置成true,angualr将监视对象每一个属性的变化


    接下的栗子是之前购物车的升级版

    <div ng-controller="CartController">
    <div ng-repeat="item in items">
    <span>{{item.title}}</span>
    <input ng-model="item.quantity">
    <span>{{item.price | currency}}</span>
    <span>{{item.price * item.quantity | currency}}</span>
    </div>
    <div>Total: {{totalCart() | currency}}</div>
    <div>Discount: {{bill.discount | currency}}</div>
    <div>Subtotal: {{subtotal() | currency}}</div>
    </div>
    CartController:

    function CartController($scope) {
    $scope.bill = {};
    $scope.items = [
    {title: 'Paint pots', quantity: 8, price: 3.95},
    {title: 'Polka dots', quantity: 17, price: 12.95},
    {title: 'Pebbles', quantity: 5, price: 6.95}
    ];
    $scope.totalCart = function() {
    var total = 0;
    for (var i = 0, len = $scope.items.length; i < len; i++) {
    total = total + $scope.items[i].price * $scope.items[i].quantity;
    }
    return total;
    }
    $scope.subtotal = function() { return $scope.totalCart() - $scope.bill.discount;
    };
    function calculateDiscount(newValue, oldValue, scope) {
    $scope.bill.discount = newValue > 100 ? 10 : 0;
    }
    $scope.$watch($scope.totalCart, calculateDiscount);
    }

    注意:在totalCart()建立一个监视,totalCart()用于计算该支付的总额,每当其发生变化时,watch函数就会调用calculateDiscount(),然后我们设置对这个值适当的折扣。假设总值达昱100$,就设置折扣为10$,否则为0;

    上述结果



    对于watch性能,我们还须要注意一些潜在的性能问题

    在上述样例中,尽管其可以正常的执行,但假设我们在totoalCart()加一个调试的断电,你将会看到它被调用了六次才渲染页面,而在代码中我们非常easy跟踪到三次,

    1.模版中{{totalCart|currency}}

    2.Subtotal()函数

    3.$watch()函数

    而angualr为了验证传递的模型变化已经全然传递,会再执行多一次,所以总共执行六次,而这样的情况非常easy造成一个循环依赖。所以我们提供了下面的集中解决的方法

    一种是在数组的每一个元素上创建爱你$watch监控变化,不过这样不过只计算了$scope属性中的total,discount,subtotal

    <div>Total: {{bill.total | currency}}</div>
    <div>Discount: {{bill.discount | currency}}</div>
    <div>Subtotal: {{bill.subtotal | currency}}</div>

    然后在控制器中,我们监视数组的元素,一旦数组发生不论什么变化,均会调用函数又一次计算总价

    function CartController($scope) {
    $scope.bill = {};
    $scope.items = [
    {title: 'Paint pots', quantity: 8, price: 3.95},
    {title: 'Polka dots', quantity: 17, price: 12.95},
    {title: 'Pebbles', quantity: 5, price: 6.95}
    ];
    var calculateTotals = function() {
    var total = 0;
    for (var i = 0, len = $scope.items.length; i < len; i++) {
    total = total + $scope.items[i].price * $scope.items[i].quantity;
    }
    $scope.bill.totalCart = total;
    $scope.bill.discount = total > 100 ? 10 : 0;
    $scope.bill.subtotal = total - $scope.bill.discount;
    };
    $scope.$watch('items', calculateTotals, true);
    }

    注意:在$scope指定了一个字符串的items,items将作为表达式在调用它的$scope作用域中运行

    然后因为我们监视数组中的全部项,angualar不得不正确它进行一份拷贝用于对照,假设遇到一个具有非常多元素的列表时,可能会导致执行效率减少

    所以我们能够给$watch仅仅传一个用于又一次计算属性的watchFn


    $scope.$watch(function() {
    var total = 0;
    for (var i = 0; i < $scope.items.length; i++) {
    total = total + $scope.items[i].price * $scope.items[i].quantity;
    }
    $scope.bill.totalCart = total;
    $scope.bill.discount = total > 100 ? 10 : 0;
    $scope.bill.subtotal = total - $scope.bill.discount;
    });

    四、组织模块的注入:


    函数 定义
    provider(name,object OR constructor()) 可配置,有复杂逻辑的服务,可用于构造函数
    factory(name,$getFunction()) 不可配置,有复杂逻辑的服务,定义一个函数,调用时返回服务实例
    service(name,constructor()) 具有简单逻辑,用于创建服务实例

    在这里,我们利用之前讨论过的items演示样例使用factory()

    // Create a module to support our shopping views
    var shoppingModule = angular.module('ShoppingModule', []);
    // Set up the service factory to create our Items interface to the
    // server-side database 
    shoppingModule.factory('Items', function() {
    var items = {};
    items.query = function() {
    // In real apps, we'd pull this data from the server... 
    return [
    {title: 'Paint pots', description: 'Pots full of paint', price: 3.95}, {title: 'Polka dots', description: 'Dots with polka’, price: 2.95},
    {title: 'Pebbles', description: 'Just little rocks', price: 6.95}
    ];
    };
    return items;
    });

    <html ng-app='ShoppingModule'>
    <body ng-controller="ShoppingController">
    <h1>Shop!</h1>
    <table> <tr ng-repeat=”item in items”></tr>
    <td>{{item.title}}</td>
    <td>{{item.description}}</td>
    <td>{{item.price | currency}}</td>
    </tr>
    </table>
    </div>

    五、用过滤器过滤数据

    过滤器同意你申明怎样展示给用户的数据转换后插入到你的模版中。

    {{ expression | filterName : parameter1 : ...parameterN }}

    当中expression为随意表达式,filterName为你想用的过滤器的名称,传递给过滤器的參数用冒号隔开,

    而angular有几个自带过滤器如:date,number,uppercase等,在这里就不多介绍,主要我们来学习假设自己创建一个自己定义过滤器

    以下样例是通过filter()函数构造一个名为titleCase的过滤器,其作用是将句子中每一个单词的首字母大写

    var homeModule = angular.module('HomeModule', []);
    homeModule.filter('titleCase', function() {
    var titleCaseFilter = function(input) {
    var words = input.split(' ');
    for (var i = 0; i < words.length; i++) {
    words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1);
    }
    return words.join(' ');
    };
    return titleCaseFilter;
    });

    相应的HTML模版

    <body ng-app='HomeModule' ng-controller="HomeController">
    <h1>{{pageHeading | titleCase}}</h1>
    </body>

    通过控制器赋值给模型变量

    function HomeController($scope) {
    $scope.pageHeading = 'behold the majesty of your page title';
    }

    执行结果例如以下图





  • 相关阅读:
    InstallShield自定义对话框模板代码(转)
    破解汇编知识(转)
    Openrowset数据库远程操作
    SQL类似sleep延时语句
    C#结束线程
    JavaScript中相应ActiveX事件
    Visual C# .NET 命令行编辑器
    AfxBeginThread
    atoi,atol,strtod,strtol,strtoul类型转换(转)
    SQLServer PadLeft,PadRight
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/3823945.html
Copyright © 2020-2023  润新知