如何在引导程序中双向数据绑定以动态设置幻灯片切换



我对编程很陌生,非常感谢有关 SlideToggle 数据绑定的任何帮助

我这里有一个JSFiddle链接:https://jsfiddle.net/haLxj1uy/(代码也在下面提供(


.HTML:

<label class="switch">
    <input type="checkbox" id="togBtn">
    <div class="slider round">
        <span class="on">ON</span>
        <span class="off">OFF</span>
    </div>
</label>

.CSS:

.switch {
    position: relative;
    display: inline-block;
    width: 90px;
    height: 34px;
}
.switch input {display:none;}
.slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: #ca2222;
    -webkit-transition: .4s;
    transition: .4s;
 }
.slider:before {
  position: absolute;
  content: "";
  height: 26px;
  width: 26px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
}
input:checked + .slider {
  background-color: #2ab934;
}
input:focus + .slider {
  box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
  -webkit-transform: translateX(55px);
  -ms-transform: translateX(55px);
  transform: translateX(55px);
}
.on {
  display: none;
}
.on, .off {
  color: white;
  position: absolute;
  transform: translate(-50%,-50%);
  top: 50%;
  left: 50%;
  font-size: 10px;
  font-family: Verdana, sans-serif;
}
input:checked+ .slider .on {
    display: block;
}
input:checked + .slider .off {
    display: none;
}
/* Rounded sliders */
.slider.round {
  border-radius: 34px;
}
.slider.round:before {
  border-radius: 50%;
}

在我的JavaScript中,我做了一个简单的函数:

test(event) { console.log(event.target.value); }

但是,当我滑动开关打开/关闭时,两个控制台.log都是on(test 函数将触发两次,因为我会让它从"关闭"->"开"和"开"->"关"(。所以我有几个问题是:

  • 如何根据变量(条件(动态设置滑块切换?
  • 如何从 JavaScript 中的幻灯片切换中正确获取真/假(或开/关(?

在角度中,建议使用本机 DOM 元素启用双向数据绑定的方法是实现 ControlValueAccessor 接口。 通过实现此接口,您的本机 DOM 元素与 Angular 表单(模板驱动和响应式表单(兼容,并且可以与 FormControlngModel 指令一起使用。

这是一篇很好的文章,展示了ControlValueAccessor如何适应更大的图景。

这是滑块的ControlValueAccessor实现;

custom-slide.component.ts

import { Component, Renderer2, forwardRef, ViewChild, ElementRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms"
export const CUSTOM_SLIDE_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => CustomSlideComponent),
  multi: true,
};
@Component({
  selector: 'my-custom-slide',
  templateUrl: './custom-slide.component.html',
  styleUrls: ['./custom-slide.component.css'],
  providers: [CUSTOM_SLIDE_VALUE_ACCESSOR]
})
export class CustomSlideComponent implements ControlValueAccessor {
  @ViewChild("inp", { static: true }) input: ElementRef<HTMLInputElement>;
  onChange = (_: any) => { };
  onTouched = () => { };
  constructor(private _renderer: Renderer2) { }
  writeValue(value: any): void {
    this._renderer.setProperty(this.input.nativeElement, 'checked', value);
  }
  registerOnChange(fn: (_: any) => {}): void { this.onChange = fn; }
  registerOnTouched(fn: () => {}): void { this.onTouched = fn; }
  setDisabledState(isDisabled: boolean): void {
    this._renderer.setProperty(this.input.nativeElement, 'disabled', isDisabled);
  }
}

custom-slide.component.html

<label class="switch">
  <input #inp type="checkbox" id="togBtn" (change)="onChange($event.target.checked)" (blur)="onTouched()">
  <div class="slider round">
    <span class="on">ON</span>
    <span class="off">OFF</span>
  </div>
</label>

custom-slide.component.css(与你提供的CSS相同,没有任何变化。

.switch {
  position: relative;
  display: inline-block;
  width: 90px;
  height: 34px;
}
.switch input {display:none;}
.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ca2222;
  -webkit-transition: .4s;
  transition: .4s;
}
.slider:before {
  position: absolute;
  content: "";
  height: 26px;
  width: 26px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
}
input:checked + .slider {
  background-color: #2ab934;
}
input:focus + .slider {
  box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
  -webkit-transform: translateX(55px);
  -ms-transform: translateX(55px);
  transform: translateX(55px);
}
/*------ ADDED CSS ---------*/
.on
{
  display: none;
}
.on, .off
{
  color: white;
  position: absolute;
  transform: translate(-50%,-50%);
  top: 50%;
  left: 50%;
  font-size: 10px;
  font-family: Verdana, sans-serif;
}
input:checked+ .slider .on
{display: block;}
input:checked + .slider .off
{display: none;}
/*--------- END --------*/
/* Rounded sliders */
.slider.round {
  border-radius: 34px;
}
.slider.round:before {
  border-radius: 50%;}

你可以在这样的任何地方使用它;

<my-custom-slide [(ngModel)]="slideValue"></my-custom-slide>

最后,这是一个工作演示>>> https://stackblitz.com/edit/angular-w7n6er

最新更新