[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自己特有的选项 ...
随机推荐
- QT_2
1.默认生成代码的含义(.pro)
- 在实现栈中原来功能的基础上,获得一个栈中最小值,要求时间复杂度 bigO(1)
思路: 准备两个栈 stackData stackMin package my_basic; import java.util.Stack; public class GetMinStack { St ...
- 数论基础之组合数&计数问题
一.组合数:问题引入:现在有 n 个球,取其中的 k 个球,问一共有多少种方式?答案: 公式直观解释:我们考虑有顺序地取出 k 个球:第一次有 n 种选择,第二次有 n-1 种选择,...,第 k 次 ...
- c++类的单目和双目运算符的重定义
这个里面需要注意的是对于双目运算符,像是加号,如果是复数加整数是一种情况,而整数加复数又是另一种情况,所以需要重定义两次. 而对于单目运算符,如果是前缀的,直接重定义就可以了,但是如果是后缀的,我们在 ...
- 14. PARAMETERS
14. PARAMETERS PARAMETERS表提供有关存储例程(存储过程和存储函数)的参数以及存储函数的返回值的信息. PARAMETERS表不包含内置SQL函数或用户定义函数(UDF). 参数 ...
- bacula快速部署
快速部署: Server端:DD.SD.Monitor.Console均部署在Server上Client端:FD Server端部署:上传事先下载的源码包 tar xvf bacula-9.2.0.t ...
- Linux查看配置文件中未被注释的有效配置行
grep 命令示例——去掉注释 $ grep -v "^#" /path/to/config/file $ grep -v "^#" /etc/apache2/ ...
- laravel 集成 swagger插件
原文链接:https://medium.com/@mahbubkabir/discovering-swagger-in-laravel-rest-apis-cb0271c8f2 1.composer ...
- python基础知识11-文件操作
文件 装饰器,装饰函数或者类的方法. 1.文件的基本操作 打开文件: 注意绝对路径与相对路径. path = 'text.txt' path = r'/home/pyvip/py_case/text. ...
- include_once 问题
最近在做微信小程序,在include_once 微信文件后,该方法return 前面会用特殊字符,导致我return 给前端的本来是json串变成了字符 解决方法 : ob_clean(); retu ...