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. C-基础:冒泡排序

    #include <fstream> #include <iostream.h> //--------------------------------------------- ...

  2. dockerfile note

    dockerfile note reference summary defination docker can build images automatically by reading the in ...

  3. 微信小程序入口场景的问题整理与相关解决方案

    前言 最近一段时间都在做小程序. 虽然是第二次开发小程序,但是上次做小程序已经是一年前的事了,所以最终还是被坑得死去活来. 这次是从零开始开发一个小程序,其实除了一些莫名其妙的兼容性问题,大多数坑点都 ...

  4. Tunnelier使用说明

    Tunnelier与MyEnTunnel类似,但是功能更加强大.MyEnTunnel小巧易用,如何使用MyEnTunnel可以参考 MyEnTunnel使用说明 这里列下Tunnelier的优点: 1 ...

  5. strong&weak

    copy:建立一个索引计数为1的对象,然后释放旧对象 对NSString对NSString 它指出,在赋值时使用传入值的一份拷贝.拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协议 ...

  6. node.js从入门到放弃(二)

    上章讲了学习node,应该去学习什么,对这些框架去进行学习现在咋们聊聊如何用原生来进行操作 主要来讲一下events-事件触发器 events是什么东西呢?他的英文翻译,活动,事件的意思,在计算机语言 ...

  7. Centos7中yum安装jdk及配置环境变量

    系统版本 [root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) #安装之前先查看一下有无系统 ...

  8. cmd启动MySQL服务器发生错误

    Mysql net start mysql启动,提示发生系统错误 5 拒绝访问  原文:https://blog.csdn.net/angel_guoo/article/details/7919037 ...

  9. systemverilog:task

    1.task declaration 个人喜欢ANSI C格式的声明: task mytask(output int x,input logic y); ...... endtask 注意端口列表的方 ...

  10. VMware搭建内网并通过iptables端口转发联网

    整体流程图 配置Server1 新建两块网卡 一块网卡设置为桥接模式,另外一块设置为仅主机模式 查看两块网卡配置 root@ubuntu:~# ifconfig ens33 Link encap:Et ...