Lors du développement avec Angular, nous utilisons souvent la liaison dans Angular - liaison d'entrée du modèle à la vue, liaison de sortie de la vue au modèle et liaison entre la vue et le modèle Liaison bidirectionnelle. La raison pour laquelle ces valeurs liées peuvent être synchronisées entre la vue et le modèle est due à la détection des changements dans Angular.
Pour faire simple, la détection de changement est utilisée par Angular pour détecter si les valeurs liées entre la vue et le modèle ont changé. Lorsqu'il est détecté que les valeurs liées dans le modèle ont changé, elle est synchronisée avec la vue. Au contraire, lorsqu'il est détecté que la valeur liée sur la vue change, la fonction de liaison correspondante est rappelée.
La clé de la surveillance des changements est de savoir comment surveiller si les valeurs liées ont changé à la plus petite granularité et dans quelles circonstances ces valeurs liées seront provoquées. changer de drap de laine ? Nous pouvons jeter un œil à plusieurs scénarios couramment utilisés :
@Component({ selector: 'demo-component', template: ` <h1>{{name}}</h1> <button (click)="changeName()">change name</button> ` }) export class DemoComponent { name: string = 'Tom'; changeName() { this.name = 'Jerry'; } }
Nous lions l'attribut name dans le modèle via des expressions d'interpolation. Lorsque change name按钮
est cliqué, la valeur de l'attribut name est modifiée et le contenu affiché dans la vue modèle change également.
@Component({ selector: 'demo-component', template: ` <h1>{{name}}</h1> ` }) export class DemoComponent implements OnInit { name: string = 'Tom'; constructor(public http: HttpClient) {} ngOnInit() { // 假设有这个./getNewName请求,返回一个新值'Jerry' this.http.get('./getNewName').subscribe((data: string) => { this.name = data; }); } }
Nous avons envoyé une requête Ajax au serveur dans la fonction ngOnInit de ce composant. Lorsque cette requête renvoie le résultat, elle modifiera également la liaison sur le courant. vue modèle. La valeur de l’attribut de nom spécifié.
@Component({ selector: 'demo-component', template: ` <h1>{{name}}</h1> ` }) export class DemoComponent implements OnInit { name: string = 'Tom'; constructor() {} ngOnInit() { // 假设有这个./getNewName请求,返回一个新值'Jerry' setTimeout(() => { this.name = 'Jerry'; }, 1000); } }
Nous définissons une tâche planifiée dans la fonction ngOnInit de ce composant. Lorsque la tâche planifiée est exécutée, elle modifiera également la liaison sur la vue actuelle. . La valeur de l'attribut name.
En fait, il n'est pas difficile de constater que les trois situations ci-dessus ont une chose en commun, à savoir ces événements qui font que la valeur contraignante les changements se produisent tous de manière asynchrone.
Angular ne capture pas les changements dans les objets. Il utilise le timing approprié pour vérifier si la valeur de l'objet a été modifiée. Ce timing est l'occurrence de ces événements asynchrones.
Ce timing est contrôlé par le service NgZone. Il obtient le contexte d'exécution de l'ensemble de l'application et peut capturer l'occurrence, l'achèvement ou l'exception d'événements asynchrones associés, puis pilote l'implémentation angulaire de mécanisme de suivi des changements.
Grâce à l'introduction ci-dessus, nous comprenons à peu près comment la détection des changements est déclenchée, puis comment la surveillance des changements dans Angular est effectuée. Tissu de laine ?
La première chose que nous devons savoir est que pour chaque composant, il existe un moniteur de modifications correspondant ; c'est-à-dire que chaque composant correspond à un changeDetector
, que nous pouvons obtenir par injection de dépendances dans le composant <. 🎜>. changeDetector
, alors les changeDetector
sont également organisés dans une arborescence. changeDetector
@Component({ selector: 'demo-child', template: ` <h1>{{title}}</h1> <p>{{paramOne}}</p> <p>{{paramTwo}}</p> ` }) export class DemoChildComponent { title: string = '子组件标题'; @Input() paramOne: any; // 输入属性1 @Input() paramTwo: any; // 输入属性2 }
@Component({ selector: 'demo-parent', template: ` <h1>{{title}}</h1> <demo-child [paramOne]='paramOneVal' [paramTwo]='paramTwoVal'></demo-child> <button (click)="changeVal()">change name</button> ` }) export class DemoParentComponent { title: string = '父组件标题'; paramOneVal: any = '传递给paramOne的数据'; paramTwoVal: any = '传递给paramTwo的数据'; changeVal() { this.paramOneVal = '改变之后的传递给paramOne的数据'; } }
Lorsque nous cliquons sur le bouton de DemoParentComponent, il sera rappelé à la méthode changeVal, puis l'exécution de la surveillance des modifications sera déclenchée. Le processus de surveillance des modifications est le suivant :
Tout d'abord, la détection des modifications démarre à partir de DemoParentComponent Start :OnPush 与 Default 之间的差别:当检测到与子组件输入绑定的值没有发生改变时,变化检测就不会深入到子组件中去。
上面说到我们可以修改组件元数据属性 changeDetection 来修改组件的变化监测策略(ChangeDetectionStrategy.Default 或 ChangeDetectionStrategy.OnPush),除了这个,我们还可以使用 ChangeDetectorRef 来更加灵活的控制组件的变化监测。
Angular 在整个运行期间都会为每一个组件创建 ChangeDetectorRef 的实例,该实例提供了相关方法来手动管理变化监测。有了这个类,我们自己就可以自定义组件的变化监测策略了,如停止/启用变化监测或者按指定路径变化监测等等。
相关方法如下:
markForCheck():把根组件到该组件之间的这条路径标记起来,通知Angular在下次触发变化监测时必须检查这条路径上的组件。
detach():从变化监测树中分离变化监测器,该组件的变化监测器将不再执行变化监测,除非再次手动执行reattach()方法。
reattach():把分离的变化监测器重新安装上,使得该组件及其子组件都能执行变化监测。
detectChanges():手动触发执行该组件到各个子组件的一次变化监测。
使用方法也很简单,直接在组件中注入即可:
@Component({ selector: 'demo-parent', template: ` <h1>{{title}}</h1> ` }) export class DemoParentComponent implements OnInit { title: string = '组件标题'; constructor(public cdRef: ChangeDetectorRef) {} ngOnInit() { this.cdRef.detach(); // 停止组件的变化监测,看需求使用不同的方法 } }
相关推荐:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!