[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自己特有的选项 ...
随机推荐
- vscode setting.json
setting.json { "sync.gist": "#github的码##", "sync.lastUpload": "20 ...
- Hadoop伪集群部署
环境准备 [root@jiagoushi ~]# yum -y install lrzsz 已加载插件:fastestmirror Repository 'saltstack-repo': Error ...
- MFC限制窗口大小
MFC限制窗口大小 使用:WM_GETMINMAXINFO message void OnGetMinMaxInfo(MINMAXINFO* lpMMI) { lpMMI->ptMinTrack ...
- VC-基础:常用的安全CRT函数
常用的安全CRT函数 安全CRT(C Runtime Library = C运行时间库)函数,是微软公司对C/C++语言的扩展.它在原来函数名后添加了“_s”后缀:一般返回出错代码:并将原来的函数返回 ...
- hibernate5.x版本org.hibernate.MappingException: Unknown entity问题
/* * //创建hibernate配置对象 Configuration cfg = new Configuration(); cfg.configure("hibernate.cfg.xm ...
- ES6 第五章 字符串的新增方法 具体参照 http://es6.ruanyifeng.com
1.FormCodePoint 对象方法 用于从 Unicode 码点返回对应字符,可以识别原来es5不能识别的大于0xFFFF的码点. String.fromCodePoint(0x20BB7) / ...
- 解决Invalid bound statement (not found)(Mybatis的Mapper绑定问题)
一.问题描述 使用mybatis的项目在本地可以正常运行,但当使用maven或Jenkins打包部署到服务器上时出现了绑定错误,异常信息为: org.apache.ibatis.binding.Bin ...
- 【2019-5-26】python:字典、常用字符串处理方法及文件操作
一.数据类型:字典 1.字典: 1.1定义字典:dict={'key':'value'} 1.2字典与列表相比,字典取值快,可直接找到key 1.3字典是无序的,不能根据顺序取值 1.4多个元素用逗号 ...
- 什么是session?
Session一般译作会话.从不同的层面看待session,它有着类似但不全然相同的含义.比如,在web应用的用户看来,他打开浏览器访问一个电子商务网站,登录.并完成购物直到关闭浏览器,这是一个会话. ...
- Mysql 一对多关系建立(在navicat中)
一个孩子只有一个妈妈,而一个妈妈可以有多个孩子,这是典型的一对多的关系,这里采用navicat图形化界面建立二者的关系. 第一步:创建mother表,如下图: 第二步:创建children表,在chi ...