[Angular] Refactor Angular Component State Logic into Directives
Allow the base toggle to be a tag (<toggle>) or attribute (<div toggle>). The <toggle> component has become less opinionated about the view, but has now taken on some responsibilities managing state. We’ll decouple the state management piece by moving it into the toggleProvider directive. The toggleProvider directive provides state for all the <toggle-off>, <toggle-on> and <toggle-button> components inside it.
For toggle component we made in previous post.
@Component({
selector: 'toggle',
template: '<ng-content></ng-content>',
})
As you can see, it use 'ng-content' inside template which means that it doesn't actually needs a template, we can consider ToggleComponent as a directive.
So we can modifiy ToggleComponet to ToggleDirective:
import { Directive, Input, Output, EventEmitter } from '@angular/core'; @Directive({
selector: 'toggle, [toggle]'
})
export class ToggleDirective {
@Input() on: boolean;
@Output() toggle: EventEmitter<boolean> = new EventEmitter(); setOnState(on: boolean) {
this.on = on;
this.toggle.emit(this.on);
}
}
So we can change the usage in app.component.html:
<div toggle (toggle)="onToggle($event)">
<toggle-on>On</toggle-on>
<toggle-off>Off</toggle-off>
<toggle-off>Off</toggle-off>
<other-component></other-component>
<toggle-button></toggle-button>
</div>
Then change all the dependencies injection for toggle-on/off/button component, the application should still works.
One problem for the current directive implementations is that each toggle directives are isolated:
Most of times, isolated directives are OK, but in some cases, if you want to share the state between two or more directives. You have to do some extra works.
Write ToggleProviderDirective for reference ToggleDirective.
state <-- ToggleDirective <-- ToggleProviderDirective
So ToggleDirective is managing the state, if we want to share the state, we create ToggleProviderDirective, it takes ToggleDirective as input, so that we can share one ToggleDirective thoughts multi directives.
import { Directive, Input, Output, Host, OnChanges, SimpleChanges, Optional } from '@angular/core';
import {ToggleDirective} from './toggle.directive'; @Directive({
exportAs: 'toggleProvider',
selector: 'toggle, [toggle], [toggleProvider]',
})
export class ToggleProviderDirective implements OnChanges { @Input() toggleProvider: ToggleDirective; toggle: ToggleDirective = this.toggleDirective; constructor(
// Reference the toggle directive on the same host element
@Host() @Optional() private toggleDirective: ToggleDirective
) { } ngOnChanges(changes: SimpleChanges) {
const {toggleProvider} = changes;
if (toggleProvider) {
this.toggle = this.toggleProvider || this.toggleDirective;
}
}
}
Also need to change the reference for toggle-on/off/button:
import { Component } from '@angular/core'; import { ToggleProviderDirective } from './toggle.toggleProvider.directive'; @Component({
selector: 'toggle-button',
template: '<switch [on]="toggleProvider.toggle.on" (click)="onClick()" ></switch>',
})
export class ToggleButtonComponent {
constructor(public toggleProvider: ToggleProviderDirective) {} onClick() {
this.toggleProvider.toggle.setOnState(!this.toggleProvider.toggle.on);
}
}
[Angular] Refactor Angular Component State Logic into Directives的更多相关文章
- Exploring the Angular 1.5 .component() method
Angular 1.5 introduced the .component() helper method, which is much simpler than the.directive() de ...
- [Angular 2] Exposing component properties to the template
Showing you how you can expose properties on your Controller to access them using #refs inside of yo ...
- [React] Update Component State in React With Ramda Lenses
In this lesson, we'll refactor a React component to use Ramda lenses to update our component state. ...
- [Angular] Use Angular components in AngularJS applications with Angular Elements
When migrating AngularJS (v1.x) applications to Angular you have different options. Using Angular El ...
- angular 2 angular quick start Could not find HammerJS
Angular2 的material中 引用了 hammerjs,遇到Could not find HammerJS错误,正确的步骤如下: 需要在如下位置增加 对material 和 hammerjs ...
- ASP.NET Core 2.1 Web API + Identity Server 4 + Angular 6 + Angular Material 实战小项目视频
视频简介 ASP.NET Core Web API + Angular 6的教学视频 我是后端开发人员, 前端的Angular部分讲的比较差一些, 可以直接看代码!!!! 这是一个小项目的实战视频, ...
- React 手稿 - Component state
Component state 实例: import React, { PureComponent } from 'react'; export default class extends PureC ...
- [Angular] Expose Angular Component Logic Using State Reducers
A component author has no way of knowing which state changes a consumer will want to override, but s ...
- Angular(二) - 组件Component
1. 组件Component示例 2. Component常用的几个选项 3. Component全部的选项 3.1 继承自@Directive装饰器的选项 3.2 @Component自己特有的选项 ...
随机推荐
- aapt环境变量配置
D:\android-sdk_r24.4.1-windows\android-sdk-windows\build-tools\28.0.2 将aapt路径添加到path中, 打开cmd 输入aapt
- Keil Debug (printf) Viewer
Debug (printf) Viewer Home » µVision Windows » Debug (printf) Viewer The Debug (printf) Viewer windo ...
- ssh 带密码私钥 输入密码
$ssh-agent bash $ssh-add -k ~/.ssh/id_rsa Enter passphrase for /home/ubuntu/.ssh/id_rsa: Identity ad ...
- ubuntu18.04server 真机无法自动获取IP解决方法
输入命令ip a,查看自己网卡编号,比如我的就是ens33 因为此图为虚拟机搭建的,所以网卡名称为ens33,如果是真机的话则是enp0s**的名字 2.修改netwlpan文件 1 sudo vim ...
- sqlserver还原3101
1.出现错误"3101" 2.解决办法:删除数据库之后还原(有风险)或者获得数据库的独占访问权(用sql语句) 参考:https://www.2cto.com/database/2 ...
- Manjaro安装SS客户端
首先安装shadowsocks-libev sudo pacman -S shadowsocks-libev 然后编辑配置文件 vim /etc/shadowsocks/config.json { & ...
- python基础003
1. list 1.1 基础 list是一组有序的集合序列,可以包含任何类型且不必相同,并支持嵌套.采用如下创建方式: li = ["spam",2.0,5,[10,20]] 列表 ...
- Cable master 求电缆的最大长度(二分法)
Description Inhabitants of the Wonderland have decided to hold a regional programming contest. The J ...
- [SQL]数据库中对值为数字,存储格式为varchar类型的字段进行排序
如果要对数据库中某存储数字的列(存储类型不为int)进行排序,可以在order by 里对该列进行转换, 即如 order by cast(mycolumn as int) desc
- luogu2633 Count on a tree
主席树放到树上而已 #include <algorithm> #include <iostream> #include <cstdio> using namespa ...