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的更多相关文章

  1. Exploring the Angular 1.5 .component() method

    Angular 1.5 introduced the .component() helper method, which is much simpler than the.directive() de ...

  2. [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 ...

  3. [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. ...

  4. [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 ...

  5. angular 2 angular quick start Could not find HammerJS

    Angular2 的material中 引用了 hammerjs,遇到Could not find HammerJS错误,正确的步骤如下: 需要在如下位置增加 对material 和 hammerjs ...

  6. ASP.NET Core 2.1 Web API + Identity Server 4 + Angular 6 + Angular Material 实战小项目视频

    视频简介 ASP.NET Core Web API + Angular 6的教学视频 我是后端开发人员, 前端的Angular部分讲的比较差一些, 可以直接看代码!!!! 这是一个小项目的实战视频, ...

  7. React 手稿 - Component state

    Component state 实例: import React, { PureComponent } from 'react'; export default class extends PureC ...

  8. [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 ...

  9. Angular(二) - 组件Component

    1. 组件Component示例 2. Component常用的几个选项 3. Component全部的选项 3.1 继承自@Directive装饰器的选项 3.2 @Component自己特有的选项 ...

随机推荐

  1. SQL分组聚合查询练习(SQL Server和Oracle相似)20190514

    先建表 CREATE TABLE [dbo].[orderdt_jimmy]( ,) NOT NULL, [order_nid] [int] NOT NULL, ) NOT NULL, [qty] [ ...

  2. python编码的初识

    用途: ​ 密码本:二进制 与 文字的对应关系 ASCII: ​ 最早的密码本:二进制与 英文字母,数字,特殊字符的对应关系 格式: 01100001 a 01100010 b 字节数: ​ 英文1个 ...

  3. EBS ORACLE使用API批量取消销售订单

    需要切换组织,还有用户的id.下面红色字体代表要修改的地方. /*BEGIN MO_GLOBAL.INIT('M'); MO_GLOBAL.set_policy_context ('S',); FND ...

  4. win手动编译JAVA 未完成(系统path未加入文章)

    java 下面存.BAT dir /s /B *.java > sources.txtjavac @sources.txt -bootclasspath "C:\Users\88797 ...

  5. 漫谈Word2vec之skip-gram模型

    https://zhuanlan.zhihu.com/p/30302498 陈运文 ​ 复旦大学 计算机应用技术博士 40 人赞同了该文章 [作者] 刘书龙,现任达观数据技术部工程师,兴趣方向主要为自 ...

  6. 前端学习日记-vue cli3.0环境搭建

    卸载老版本的 vue-cli : npm uninstall vue-cli -g 安装新版本的 : npm install -g @vue/cli --安装新版本cli 同时nodeJS 要更新至 ...

  7. hdu 6441 Find Integer(费马大定理+勾股数)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6441(本题来源于2018年中国大学生程序设计竞赛网络选拔赛) 题意:输入n和a,求满足等式a^n+b^ ...

  8. HDU-1297-Children’s Queue

    Children’s Queue 这道题是排序问题,可以用递归方法解决. 计算F(n): 一:当最后一个是男孩M时候,前面n-1个随便排出来,只要符合规则就可以,即是F(n-1): 二:当最后一个是女 ...

  9. markdown pad激活

    <iframe src="></iframe> ---恢复内容开始--- 注册码 Soar360@live.com GBPduHjWfJU1mZqcPM3BikjYK ...

  10. CentOS 7 设置开机自启动

    创建脚本:    #!/bin/bash    echo "hello!" # 启动虚拟环境    cd /data/env/crmenv/bin/    source activ ...