zoukankan      html  css  js  c++  java
  • 5.把作用域实现为数据模型

    AngularJS作用域:提供了在一个模型中表示的数据,把AngularJS应用程序的其他组件,模块,服务和模板都绑定在一起

    1.了解作用域

    一个应用程序的数据模型(结合视图,业务逻辑,服务器端数据)

    1.1.根作用域和应用程序之间的关系

    应用程序启动,根作用域创建。($rootScope将数据储存在应用层)

    在run()块初始化(也可在模块组件中访问)。

    angular.module('myApp',[]).run(function($rootScope){
       $rootScope.rootValue=5; 
    })
    .controller('myController',function($scope,$rootScope){
       $scope.value=10; 
       $scope.difference=function(){
            return $rootScope.rootValue-$scope.value;
        } 
    })
    

    1.2.作用域和控制器之间的关系

    控制器:扩大作用域来提供业务逻辑。(Model对象上的controller()方法创建:把控制器注册为模块中的提供器,实例的创建发生在ng-controller指令被链接到AngularJS模板) 

    angular.module('myApp',[]).
    value('start',200).controller('Counter',['$scope','start',function($scope,startingValue){
        //新子作用域创建,$scope访问,start提供器被注入到控制器,作为startingValue被传递到控制器函数
    }])     

    控制器负责连接到该作用域内的任何业务逻辑。意味着处理对作用域的更新更改,操作作用域值,发出基于该作用域的状态的事件

    实现依赖注入的控制器,初始化值,inc(),dec(),calcDiff() 实现基本逻辑

    var myModule = angular.module('myApp', []);
    myModule.value('start', 200);
    myModule.controller('Couter', ['$scope', start, function($scope, start) {
        $scope.start = start;
        $scope.current = start;
        $scope.difference = 0;
        $scope.change = 1;
        $scope.inc = function() {
            $scope.current += $scope.change;
            $scope.calcDiff();
        };
        $scope.dec = function() {
            $scope.current -= $scope.change;
            $scope.calcDiff();
        }
        $scope.calcDiff = function() {
            $scope.difference = $scope.current - $scope.start;
        };
    }])
    

    1.3.作用域和模板之间的关系

    模板为AngularJS应用程序提供视图。(HTML元素使用ng-controller属性被定义为控制器)(控制器的HTML元素及子元素内部,控制器可用于表达式和其他AngularJS功能)

    在一个作用域中的值可以用 ng-model 指令链接到模板的 <input> <select> <textarea> 元素的值中(当用户改变输入元素的值时,作用域被自动更新)

    <input type="number" ng-model="valueA">
    

    {{expression}}:把作用的属性 函数 添加到表达式

    <span ng-click="addValues(valueA,valueB)">Add Values{{valueA}}&{{valueB}}</span>
    

    ng-click指令把浏览器单击事件绑定到作用域中:addValues()函数 addValues()函数中,不是必须的 ng-click和其他的AngularJS指令会自动对表达式求值。

    <!DOCTYPE html>
    <html lang="en" ng-app="myApp">
    
    <head>
        <meta charset="UTF-8">
        <title>scope_template</title>
        
        <link rel="stylesheet" href="bootstrap.css">
    </head>
    
    <body>
    	<div class="panel panel-primary">
    		<div class="panel-heading">cal with sums(AngularJS)</div>
    		<div class="panel-body">
    			<div class="row">
    				<div class="col-md-12">
    					<form class="form-horizontal" role="form" ng-controller="SimpleTemplate">
    						<div class="form-group">
    							<label class="col-md-2 control-label">ValueA:</label>
    							<div class="col-md-10">
    								<input class="form-control" type="number" ng-model="valueA">								
    							</div>
    						</div>
    						<div class="form-group">
    							<label class="col-md-2 control-label">ValueB:</label>
    							<div class="col-md-10">
    								<input class="form-control" type="number" ng-model="valueB">								
    							</div>
    						</div>	
    						<div class="form-group">
    							<div class="col-md-offset-2 col-md-10">
    								<button class="btn btn-primary" ng-click="addValues(valueA,valueB)">click to add value</button>
    								<button class="btn btn-primary" ng-click="clearValues(valueA,valueB)">click to clear value</button>
    							</div>
    						</div>	
    						<div class="form-group">
    							<label class="col-md-2 control-label">ValueB:</label>
    							<label class="col-md-10 control-label" style="text-align: left">{{valueC}}</label>
    						</div>				
    					</form>
    				</div>
    			</div>
    		</div>
    	</div>
    	<script src="angular-1.3.0.js"></script>
    	<script type="text/javascript">
    		angular.module('myApp',[]).controller('SimpleTemplate', function($scope){
    			$scope.valueA=10;
    			$scope.valueB=20;
    			$scope.valueC=30;
    			$scope.addValues=function(v1,v2){
    				var v=angular.$rootScope;
    				$scope.valueC=v1+v2;
    			}
    			$scope.clearValues=function(v1,v2){
    				$scope.valueA=0;
    				$scope.valueB=0;
    				// v1=0;
    				// v2=0;
    			}
    		})
    	</script>
    </body>
    
    </html>
    

    (基本Angular模板,实现控制器 把多个字段链接到作用域 提供值并显示结果(CSS用bootstrap))

    1.4.作用域和后端服务器数据之间的关系

    用于AngularJS的数据 往往是后端数据源(如数据库)。

    • 经 由 AngularJS服务 来访来自数据库或其他后端资源的数据(包括读取 更新数据)
    • 确保从 数据库读出的数据 对 作用域 更新(又更新了视图),避免直接从数据库中操作HTML值 (可能会导致作用域与视图不同步) 
    • 把对 数据库或其他后端源 所做的更改 反映到作用域。可以先更新作用域,然后用一个服务对数据库进行更新 执行此操作。也可以先更新数据库,然后用来自数据库的结果在作用域内重新填充适当的值。

    1.5.作用域的生命周期

    作用域的数据经过:

    1.创建

    2.监听器注册

    3.模型变化

    4.变化观察

    5.作用域销毁

    创建阶段:一个作用域初始化时,创建阶段产生。启动应用程序会创建根作用域(ng-controller or ng-repeat)创建子作用域模板

    $scope.$digest() digest循环与浏览器事件循环互动。把对模型的更改更新到DOM元素,执行任何已注册的监听函数。

    监听注册器阶段:为作用域中的值注册监视函数。监视器自动将模型的更改传播到DOM元素

    $.scope.watchedItem='myItem';
    $scope.counter=0;
    $scope.$watch('name',function(newValue,oldValue){
       $scope.watchedItem=$scope.counter+1; 
    })
    

    模型变化阶段:发生在作用域内的数据变化时。AngularJS代码进行更改时,名为$apply()的作用域函数更新模型,调用$digest()函数更新DOM和监听器(或由$http,$timeout和$interval服务所做的更改自动在DOM中更新)

    变化观察阶段:$digest()方法被digest循环,$apply()调用或手动执行,变化观察发生。会对所有用于更改的监听器求值。发生变化,$digest调用$watch监听器更新DOM

    作用域销毁阶段:$destroy()从浏览器内存中删除作用域。停止$digest()调用并删除监听器。  

    2.实现作用域层次结构  

    作用域特点:被组织成层次结构。

    保持作用域条理,将它们与所代表的视图上下文联系起来($digest()方法用作用域层次来为适当的监听器和DOM元素传播作用域的变更)

    兄弟关系作用域:

    <div ng-controller="controllerA"></div>
    <div ng-controller="controllerB"></div>
    

    父子作用域:(controllerA是controllerB的父)

    <div ng-controller="controllerA">
        <div ng-controller="controllerB"></div>
    </div>
    

    可以从一个控制器访问父作用域的值,但不能访问它的兄弟或子作用域的值。(父元素作用域改变,子控制器中的DOM值改变)

    实现基本作用域:访问层次结构每个级别的属性

    <!DOCTYPE html>
    <html lang="en" ng-app="myApp">
    <head>
    	<meta charset="UTF-8">
    	<title>AngularJS Scope Hierarchy</title>
    </head>
    <body>
    	<div ng-controller="LevelA">
    		<h3>{{title}}</h3>
    		ValueA={{valueA}}
    		<input type="button" ng-click="inc()" value="+" />
    		<div ng-controller="LevelB">
    			<hr>
    			<h3>{{title}}</h3>
    			ValueA={{valueA}}<br/>
    			ValueB={{valueB}}
    			<input type="button" ng-click="inc()" value="+">
    			<div ng-controller="LevelC">
    				<h3>{{title}}</h3>
    				ValueA={{valueA}}<br/>
    				ValueB={{valueB}}<br/>
    				ValueC={{valueC}}
    				<input type="button" ng-click="inc()" value="+">
    			</div>
    		</div> 
    	</div>
    
    
    	<script type="text/javascript" src="angular-1.3.0.js"></script>
    	<script type="text/javascript" src="scope_hierarchy.js"></script>
    </body>
    </html>
    

    实现控制器的层次结构并呈现作用域的多个层次的结果

    angular.module('myApp', []).
    	controller('LevelA',function($scope){
    		$scope.title="Level A";
    		$scope.valueA=1;
    		$scope.inc=function(){
    			$scope.valueA++;
    		}	
    	}).
    	controller('LevelB',function($scope){
    		$scope.title="Level B";
    		$scope.valueB=1;
    		$scope.inc=function(){
    			$scope.valueB++;
    		}	
    	}).
    	controller('LevelC',function($scope){
    		$scope.title="Level B";
    		$scope.valueC=1;
    		$scope.inc=function(){
    			$scope.valueC++;
    		}	
    	});
    

    3.发出和广播活动

    作用域特点:具有在作用域层次结构内发出和广播事件的能力。

    $emit():沿着父作用域层次向上发送一个事件。任何已注册该事件的祖先作用域都会收到通知

    $broadcast():把一个事件广播给下方的子作用域层次。任何已注册该事件的后代作用域都会收到通知

    $on():处理发出或者广播的事件。scope.$on(name,listener)

    在层次结构中实现$emit() $broadcast()事件

    var myModule=angular.module('myApp', []);
    myModule.controller('Characters', function($scope){
    	$scope.names=['Frodo','Aragorn','Legolas','Gimli'];
    	$scope.currentName=$scope.names[0];
    	$scope.changeName=function(){
    		$scope.currentName=this.name;
    		$scope.$broadcast('CharacterChanged', this.name);
    	};
    	$scope.$on('CharacterDeleted', function(event,removeName){
    		var i=$scope.names.indexOf(removeName);
    		$scope.names.splice(i,1);
    		$scope.currentName=$scope.names[0];
    		$scope.$broadcast('CharacterChanged', $scope.currentName);
    	});
    })
    
    myModule.controller('Character', function($scope){
    	$scope.info={
    		'Frodo':{weapon:'Sting',race:'Hobbit'},
    		'Aragorn':{weapon:'Sword',race:'Man'},
    		'Legolas':{weapon:'Bow',race:'Elf'},
    		'Gimli':{weapon:'Axe',race:'Dwarf'}
    	};
    	$scope.currentInfo=$scope.info['Frodo'];
    	$scope.$on('CharacterChanged', function(event,newCharacter){
    		$scope.currentInfo=$scope.info[newCharacter];
    	});
    
    	$scope.deleteChar=function(){
    		console.log("delete char")
    		delete $scope.info[$scope.currentName];
    		$scope.$emit('CharacterDeleted',$scope.currentName);
    	};
    })
    

    控制器的作用域层次结构

    <!DOCTYPE html>
    <html lang="en" ng-app="myApp">
    
    <head>
        <meta charset="UTF-8">
        <title>scope events</title>
        <style type="text/css">
        div {padding: 5px;font: 18px bold;}    
        span {padding: 3px;margin: 12px;border: 5px ridge;cursor: pointer;} 
        label {padding: 2px;margin: 5px;font: 15px bold;}    
        p {padding-left: 22px;margin: 5px;}
        </style>
        <link rel="stylesheet" type="text/css" href="bootstrap.css">
    </head>
    
    <body>
        <div ng-controller="Characters" class="panel panel-primary">
            <div class="panel-body">
                <button ng-repeat="name in names" ng-click="changeName()" class="btn btn-primary">{{name}}</button>
                <div ng-controller="Character">
                    <hr>
                    <label>Name:</label>
                    <p>{{currentName}}</p>
                    <label>Race:</label>
                    <p>{{currentInfo.race}}</p>
                    <label>Weapon:</label>
                    <p>{{currentInfo.weapon}}</p>   
                    <button ng-click="deleteChar()">delete</button>                             
                </div>
            </div>
        </div>
    </body>
    	<script type="text/javascript" src="angular-1.3.0.js"></script>
    	<script type="text/javascript" src="scope_events.js"></script>
    
    </html>
    

    使用$broadcast() $emit()发送更改 通过作用域层次删除事件

    作用域与模板视图,控制器,模块和服务有直接关系。作用域也可作为数据库或其他服务器端数据源的代表。

    作用域的生命周期被链接到浏览器的事件循环中

  • 相关阅读:
    P20 HTTP 方法的安全性与幂等性
    P19 查询参数
    P18 写代码:过滤和搜索
    P17 过滤和搜索
    P16 HTTP HEAD
    golang的json操作[转]
    Android中的Service 与 Thread 的区别[转]
    iOS的block内存管理
    Go并发编程基础(译)
    golang闭包里的坑
  • 原文地址:https://www.cnblogs.com/weizaiyes/p/6038759.html
Copyright © 2011-2022 走看看