Перейти к основному содержимому

Режимы привязки

Aspid.MVVM поддерживает четыре режима привязки данных между ViewModel и View.

Содержание


Обзор

public enum BindMode
{
None = 0,
OneWay = 1,
TwoWay = 2,
OneTime = 3,
OneWayToSource = 4
}
РежимНаправлениеКогда использовать
OneWayViewModel → ViewОтображение данных (текст, прогресс-бар, иконка)
TwoWayViewModel ↔ ViewПоля ввода, слайдеры, тогглы
OneTimeViewModel → View (1 раз)Статические данные, команды
OneWayToSourceView → ViewModelПолучение ссылки на компонент, события UI

OneWay

Данные передаются только из ViewModel во View. При изменении свойства — биндер обновляет UI. Изменения UI не влияют на ViewModel.

[ViewModel]
public partial class StatsViewModel
{
[OneWayBind] private int _health;
[OneWayBind] private string _playerName;
}

Внутренняя реализация: OneWayBindableMember<T> хранит значение и event Changed. При Add() биндер сразу получает текущее значение и подписывается на Changed.

Типичные биндеры: TextBinder, ImageSpriteBinder, ImageFillBinder, GraphicColorBinder.


TwoWay

Двусторонняя синхронизация. Изменение ViewModel обновляет View, и наоборот — изменение View обновляет ViewModel.

[ViewModel]
public partial class FormViewModel
{
[TwoWayBind] private string _inputText;
[TwoWayBind] private bool _isEnabled;
[TwoWayBind] private float _volume;
}

Внутренняя реализация: TwoWayBindableMember<T> поддерживает все 4 режима. При Add() для TwoWay/OneWayToSource также подписывается на IReverseBinder<T>.ValueChanged.

Защита от цикла: Биндеры (например, InputFieldBinder) содержат флаг _isNotifyValueChanged для предотвращения бесконечной рекурсии.

Типичные биндеры: InputFieldBinder, SliderValueBinder, ToggleIsOnBinder.


OneTime

Значение передаётся один раз — при привязке. Дальнейшие изменения не отслеживаются.

[ViewModel]
public partial class PlayerViewModel
{
// Автоматически OneTime для const
[Bind] private const string Title = "Player Stats";

// Автоматически OneTime для readonly
[Bind] private readonly int _maxHealth;

// Явно OneTime
[OneTimeBind] private IRelayCommand _saveCommand;
}

Внутренняя реализация: OneTimeBindableMember<T> — singleton-per-T. Метод Add() вызывает SetValue один раз и возвращает null (нет необходимости в IBinderRemover).

Когда использовать: Команды (IRelayCommand), конфигурационные данные, статические метки.


OneWayToSource

Данные передаются только из View в ViewModel. ViewModel не может push-ить значения во View.

[ViewModel]
public partial class FormViewModel
{
[OneWayToSourceBind] private string _userInput;
}

Внутренняя реализация: OneWayToSourceBindableMember<T> — не хранит значение. Подписывается на IReverseBinder<T>.ValueChanged и передаёт изменения в ViewModel.

Когда использовать: Получение ввода пользователя без начального значения, получение ссылок на компоненты через ComponentToSourceMonoBinder.


Автоматическое определение режима

Атрибут [Bind] без параметров автоматически выбирает режим:

Тип поляОпределяемый режим
constOneTime
readonlyOneTime
Мутабельное полеTwoWay
[ViewModel]
public partial class ExampleViewModel
{
[Bind] private const string Title = "Hello"; // → OneTime
[Bind] private readonly int _id; // → OneTime
[Bind] private string _name; // → TwoWay
[Bind] private float _value; // → TwoWay
}

Рекомендация: Используйте явные атрибуты ([OneWayBind], [TwoWayBind] и т.д.) для лучшей читаемости кода.


Явное указание режима

Через параметр [Bind]

[Bind(BindMode.OneWay)] private string _text;
[Bind(BindMode.TwoWay)] private float _slider;
[Bind(BindMode.OneTime)] private IRelayCommand _command;
[Bind(BindMode.OneWayToSource)] private string _userInput;

Через атрибуты-ярлыки

[OneWayBind] private string _text;
[TwoWayBind] private float _slider;
[OneTimeBind] private IRelayCommand _command;
[OneWayToSourceBind] private string _userInput;

Оба варианта эквивалентны. Атрибуты-ярлыки — сокращённая запись.


Ограничение режимов в Inspector

На стороне биндера можно ограничить допустимые режимы привязки с помощью [BindModeOverride]:

// Только OneWay и OneTime
[BindModeOverride(BindMode.OneWay, BindMode.OneTime)]
public class TransformPositionBinder : TargetBinder<Transform, Vector3>, IVector3Binder
{
// TwoWay и OneWayToSource недоступны в Inspector
}

Некоторые биндеры поддерживают все режимы:

[BindModeOverride(IsAll = true)]
public class DebugLogBinder : MonoBinder
{
// Все режимы доступны
}

Сводная таблица

РежимViewModel → ViewView → ViewModelОбновляетсяПодходит для
OneWayПри каждом измененииОтображение данных
TwoWayПри каждом изменении (обе стороны)Интерактивные элементы
OneTimeТолько при привязкеСтатика, команды
OneWayToSourceПри изменении ViewВвод данных, получение ссылок

См. также

  • Архитектура — как работает конвейер привязки
  • ViewModel — объявление привязываемых полей
  • Биндеры — создание биндеров с конкретными режимами