在这篇文章中,我们将带领您了解AngularJS:自动检测模型的变化的全貌,包括angular自动化测试的相关情况。同时,我们还将为您介绍有关Angular2的变化检测、angular–检测变量的变化
在这篇文章中,我们将带领您了解AngularJS:自动检测模型的变化的全貌,包括angular自动化测试的相关情况。同时,我们还将为您介绍有关Angular 2的变化检测、angular – 检测变量的变化?、Angular 检测 API 中的变化、Angular 组件怎么检测Input为引用类型的变化 ?的知识,以帮助您更好地理解这个主题。
本文目录一览:- AngularJS:自动检测模型的变化(angular自动化测试)
- Angular 2的变化检测
- angular – 检测变量的变化?
- Angular 检测 API 中的变化
- Angular 组件怎么检测Input为引用类型的变化 ?
AngularJS:自动检测模型的变化(angular自动化测试)
假设我想做一些事情,只要模型的值发生更改,就可以自动运行一些代码(例如将数据保存到服务器)。通过ng-change
在每个控件上设置可能会更改模型的内容来做到这一点的唯一方法是吗?
即,使用视图,事情随着模型的改变而正确地改变,而不必显式地挂钩任何东西。是否存在可以运行保存到服务器的代码的类似物?就像是
myModel.on(''change'', function() { $.post("/my-url", ...);});
就像您可能会看到像骨干一样。
答案1
小编典典在具有{{}}
和/或ng模型的视图中,Angular $watch()
在幕后为您设置es。
默认情况下$watch
按引用进行比较。如果将第三个参数设置$watch
为true
,则Angular会“浅”监视对象的更改。对于数组,这意味着比较数组项,对于对象映射,这意味着观察属性。所以这应该做你想要的:
$scope.$watch(''myModel'', function() { ... }, true);
更新 :Angular v1.2为此添加了一个新方法`$
watchCollection():
$scope.$watchCollection(''myModel'', function() { ... });
请注意,“浅”一词用于描述比较,而不是“深”,因为未遵循引用-例如,如果监视的对象包含作为对另一个对象的引用的属性值,则不遵循该引用来进行比较另一个对象。
Angular 2的变化检测
原文地址:http://victorsavkin.com/post/110170125256/change-detection-in-angular-2
在本文中,我将深入讨论Angular 2变化检测系统。
高级概述(HIGH-LEVEL OVERVIEW)
Angular 2 的应用组件是一个树形结构的。
Angular 2 应用是一个是反应系统,变化检测是它的核心。
每个组件都有一个变化检测器负责检查其模板中定义的绑定。如{{todo.text}}和[todo]=”t”绑定。绑定的变化检测通过是从根到叶的顺序传播的。
Angular 2 不具有执行双向数据绑定的一个通用机制(你仍然可以实现双向数据绑定行为和ng-model)。这就是为什么变化检测图是一个有向树,不能有循环(即。这是一个树状)。这使得系统性能更好。而更重要的是可以保证系统更可预测和更容易推理。
它有多快?
默认情况下,变化检测经过树的每个节点检测是否改变,它适用于每个浏览器。尽管它可能看起来非常低效,但在几毫秒内angular 2可以通过成千上万的简单检查(数量是依赖于平台)。
因为JavaScript语言不能提供给我们对象的变化通知,所以Angular必须每一次保守的运行所有的检测。当然现在我们可以使用某种特性来提高性能,例如,使用不可变(immutable)或者可观察对象(observable objects),先前的Angular无法利用这一优势,但现在可以用。
不可变对象(IMMUTABLE OBJECTS)
如果一个组件只取决于它绑定的属性,并且绑定的属性是不可变的对象,则当其绑定对象变化时该组件也会发生改变。因此在变化检测树中我们可以跳过该组件的子树,直到这样的事件发生(对象发生变化)。当事件发生时,我们可以检查一次树,然后禁用它,直到下一个变化(灰色框表示禁用变化检测)。
如果我们使用不可变对象,所述变化检测树的一大块大部分时间将被禁用。
实现这个功能实在是微不足道。只要设置变化检测策略为ON_PUSH。
@Component({changeDetection:ON_PUSH}) class ImmutabletodoCmp { todo:Todo; }
可观察对象(OBSERVABLE OBJECTS)
如果一个组件只依赖于它的绑定,并且绑定是可观察的,如果这个绑定发生变化发出事件通知这个组件改变,因此在变化检测树中我们可以跳过该组件的子树,直到这样的事件(观察者发出通知)发生,当事件发生时,我们可以检查一次树,然后禁用它,直到下一个变化(灰色框表示禁用变化检测)。
这个听起来类似于不可变对象,但这是完全不同的,如果你有一个组件树使用不可变对象绑定,一个变化必须经历从根开始的所有组件检查,观察者则不会又这种情况。
用一个小例子来展示这个问题
type Observabletodo = Observable<Todo>;
type Observabletodos = Observable<Array<Observabletodo>>;
@Component({selector:’todos’})
class ObservabletodosCmp {
todos:Observabletodos;
//...
}
ObservabletodosCmp 模板
<todo *ng-for=”var t of todos” todo=”t”></todo>
ObservabletodoCmp
@Component({selector:’todo’})
class ObservabletodoCmp {
todo:Observabletodo;
//...
}
正如你所看到的,这里Todos组件只引用到一个可观察的todo数组。所以看不到Todo的变化。
当被观察的todo发生改变触发一个事件,变化检测系统将检查从根的路径到那个改变的Todo组件
如果我们的应用只使用可观察对象,当它启动时,Angular将检查所有对象。
所以第一遍检查后的状态将如下所示。
比方说第一个Todo发生变化观察者触发一个事件。该系统将切换到以下状态:
在检查App_ChangeDetector,Todos_ChangeDetector和Todo_ChangeDetector后它会回到这种状态。
假设很少发生变化,形成一个平衡的树组件,使用可观察者对象的变化检查的复杂度从O(N)到O(logN),其中,N是系统中的绑定的数量。
这种能力是不依赖于任何特定的库,简单的可观察对象实现只是几行代码的事。
可观察对象会引发级联更新吗?
可观察对象有不好的名声,因为它们会导致级联更新,任何拥有依赖于可观察对象模型框架构建大型应用的经验的人都知道我在说什么,一个可观察到的对象更新会导致一群其他可观察对象触发更新,做同样的事情。触发的一路上某处视图将被更新,这样的系统是非常难推理。
使用Angular 2的可观察对象,如上图所示将不会有这个问题,观察者通过触发事件只是标志着下一次需要检查的路径,然后通过节点树的深度优先的顺序启动正常的变化检测过程,因此,更新的顺序不会因为是否使用观察而改变。这是非常重要的。使用可观察对象将成为一个简单的优化性能方式,但不会改变您对系统思考方式。
可观察对象或者不可变对象混用?
您可以在您的应用程序的一部分使用可观察对象(例如,在一些巨大的表),这部分将获得性能优势。甚至更多,你可以撰写不同类型的组件,例如,一个“可观察组件”可以包含一个“不可变对象组件”,其本身可以包含一个“可观察对象组件”。即使在这种情况下变化检测系统将减少检查需要传播的数量变化。
转自:http://ng2.zai.io/topic/detail/news/4a1e356db11145ad
angular – 检测变量的变化?
我有以下内容:
@Input(‘name’)name:string;
我想在这个变量’name’中发生变化时调用一个函数.
可能吗?
几乎就像他们读你的想法!
总结
以上是小编为你收集整理的angular – 检测变量的变化?全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
Angular 检测 API 中的变化
您需要某种机制来通知设备服务器上的数据已更改。 HTTP 不能那样做(或者至少不擅长那样做)。一种成熟的解决方案是 WebSocket。
基本上你需要 WebSocket 客户端和服务器。在 Angular 中,您可以使用 rxjs/webSocket 作为 WebSocket 客户端。
,我不知道我是否明白你想要做什么,但你必须使用 websockets 进行实时通信,或者你可以使用轮询。
interval(1000).pipe(
switchMap(() => this.dataService.getRecipes()),distinctUntilChanged()
).subscribe(console.log);
Angular 组件怎么检测Input为引用类型的变化 ?
Angular 组件怎么检测Input为引用类型的变化 ?
Angular 组件 和 外界通信最基本的方式有2种,外界出入组件,使用Input 属性,组件传出数据,使用Output属性。Input 的属性的变化可以在ngOnChanges 钩子函数中检测到,但是如果Input属性的类型不是原始类型,如数组,数组的单个成员变化,如使用Array.splice/push 等方法改变了输入属性,改怎么监听呢?
监听 Array成员的改变
一般数组成员的改变是由一些常用的方法push splice pop, [index] = 操作引起 ,怎么监听这些操作导致数组的改变呢? 利用Angular 内置变检类IterableDiffers 来实现
实现步骤:
- 构造函数中注入 IterableDiffers 实例
// 产品Differ
private productsDiffer: IterableDiffer<any>;
constructor(private iterableDiffers:IterableDiffers) {}
- 创建一个IterableDiffer实例
ngOnInit(): void {
this.productsDiffer = this.iterableDiffers.find(this.products).create();
}
- 检测变化
ngDoCheck(): void {
// IterableDiffer.diff
const diff = this.productsDiffer.diff(this.products);
if(diff){
console.log(''products is changed in ngDoCheck'');
}
}
trackByFn
如果想监听第三级,也就是数组对象的属性的变化,以上步骤还需要调整,create 方法转入trackByFn
// 新增
private trackByFn(index: number, item: any) {
return item.name;
}
//修改
ngOnInit(): void {
this.productsDiffer = this.iterableDiffers.find(this.products)
.create(this.trackByFn);
}
测试实例代码
app-shop
import { Component, OnInit } from ''@angular/core'';
import { products } from ''./data'';
@Component({
selector: ''app-shop'',
// templateUrl: ''./shop.component.html'',
template: `
<app-product-list [products]="products"></app-product-list>
<p>
<button (click)="test1()">[index]=</button>
<button (click)="test2()">push</button>
<button (click)="test()">reset</button>
<button (click)="test3()">change object attribute</button>
</p>
`,
})
export class ShopComponent implements OnInit {
public products = [];
constructor() { }
ngOnInit(): void {
this.products = [...products];
}
// 使用数组索改变数组
test1():void {
this.products[1]= {
name:''realme'',
description:''a new brand phone'',
price: 499
}
}
// 使用push 方法
test2():void {
this.products.push({
name:''xiaomi'',
description:''you will love it'',
price: 549
});
}
// 重新赋值
test(): void {
this.products =[...products];
}
// 更深一级,改变对象的某一个属性
test3(): void {
this.products[0].name = ''iphone pro''
}
}
app-product-list
import {
Component,
Input,
IterableDiffer,
IterableDiffers,
OnInit,
SimpleChanges
} from ''@angular/core'';
// import { products } from ''../data'';
@Component({
selector: ''app-product-list'',
// templateUrl: ''./product-list.component.html'',
template:`
<h2>Products</h2>
<div *ngFor="let product of products;index as productId">
<h3>
<a [title]="product.name + '' details''" >
{{ product.name }}
</a>
</h3>
<p *ngIf="product.description">
Description: {{ product.description }}
</p>
<button (click)="share()">
Share
</button>
</div>
`,
})
export class ProductListComponent implements OnInit {
@Input() products: Array<any> = [];
// 产品Differ
private productsDiffer: IterableDiffer<any>;
constructor(private iterableDiffers: IterableDiffers) {}
ngOnInit(): void {
this.productsDiffer = this.iterableDiffers.find(this.products)
.create(this.trackByFn);
}
//
ngDoCheck(): void {
// IterableDiffer.diff
const diff = this.productsDiffer.diff(this.products);
if (diff) {
console.log(''products is changed in ngDoCheck'');
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes[''products'']) {
console.log(''products changed in ngOnChanges'');
}
}
private trackByFn(index: number, item: any) {
return item.name;
}
share(): void {
window.alert(''The product has been shared!'');
}
}
今天关于AngularJS:自动检测模型的变化和angular自动化测试的讲解已经结束,谢谢您的阅读,如果想了解更多关于Angular 2的变化检测、angular – 检测变量的变化?、Angular 检测 API 中的变化、Angular 组件怎么检测Input为引用类型的变化 ?的相关知识,请在本站搜索。
本文标签: