Как выполнить двустороннюю привязку данных, чтобы динамически установить переключатель слайдов в Bootstrap? - PullRequest
1 голос
/ 10 июля 2019

Я очень новичок в программировании и буду признателен за любую помощь с привязкой данных 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); }

Однако, когда я сдвигаю тумблер вкл / выкл, оба файла console.log равны on (функция test будет запущена дважды, потому что я перейду из «Off» -> «On» и « Вкл. -> «Выкл.»). Итак, у меня есть пара вопросов:

  • Как динамически установить ползунковый переключатель на основе переменной (условия)?
  • Как правильно получить значение true / false (или включить / выключить) при переключении слайдов в JavaScript?

1 Ответ

1 голос
/ 14 июля 2019
Угловой

, предлагаемый способ двухсторонней привязки данных с собственным элементом DOM состоит в реализации интерфейса ControlValueAccessor . благодаря реализации этого интерфейса ваш собственный элемент DOM становится совместимым с угловыми формами (как управляемыми шаблоном, так и с реактивными формами) и может использоваться как с директивами FormControl, так и с ngModel.

вот хорошая статья , которая показывает, как ControlValueAccessor вписывается в общую картину.

и это реализация ControlValueAccessor для вашего ползунка;

таможенно-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);
  }
}

заказ 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 (то же самое, что вы указали. Ничего не изменилось.)

.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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...