zoukankan      html  css  js  c++  java
  • [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);
      }
    }

  • 相关阅读:
    用rpm安装软件的常用步骤
    将应用发布到WasLiberty的两种方法
    安装 ibm-java-x86_64-sdk-6.0-9.3.x86_64.rpm 的三步骤
    人是科技的第一生产力。不重视人的价值,不尊重人的需求,不解放人的生产力,必将被互联网时代快速淘汰。
    Java保存简单偏好的类
    实用快捷键Win+L=锁屏
    判断一件事有无技术含量的标准
    主动去平事 别等事找人
    看了某些蛊惑人心的招聘广告,实在忍不住想要提醒那些跃跃欲奉献的后生们
    ubuntu16.04在英文状态下安装中文语言包的过程(法二:命令行的方式)
  • 原文地址:https://www.cnblogs.com/Answer1215/p/9764179.html
Copyright © 2011-2022 走看看