Директива s:unless

Директива s:unless представляет собой условную конструкцию, противоположную s:if. Она позволяет выполнять рендеринг элементов только тогда, когда заданное условие ложно. Это полезно для случаев, когда необходимо скрыть контент при выполнении определённого условия, без необходимости инвертировать логику в выражении.

Синтаксис

<div s:unless="условие">
    Контент отображается, если условие ложно
</div>
  • условие — это любое выражение JavaScript, возвращающее булево значение.
  • Если выражение возвращает false, элемент рендерится в DOM.
  • Если выражение возвращает true, элемент не отображается.

Примеры:

<div s:unless="isLoggedIn">
    Пожалуйста, войдите в систему, чтобы продолжить.
</div>

В этом примере <div> отображается только если переменная isLoggedIn имеет значение false или undefined.

Использование с методами и вычисляемыми свойствами

В Slim.js s:unless можно применять с методами объекта компонента или вычисляемыми свойствами:

class UserPanel extends Slim {
    constructor() {
        super();
        this.loggedIn = false;
    }

    isGuest() {
        return !this.loggedIn;
    }
}

customElements.define('user-panel', UserPanel);
<user-panel>
    <div s:unless="isGuest()">
        Контент для авторизованных пользователей
    </div>
</user-panel>

Метод isGuest() возвращает булево значение, и s:unless использует его для управления рендерингом. Элемент отобразится только если пользователь не гость.

Сочетание с s:for

Директиву s:unless можно комбинировать с s:for для фильтрации элементов массива без создания дополнительных функций фильтрации:

class TaskList extends Slim {
    constructor() {
        super();
        this.tasks = [
            { name: 'Сделать домашнее задание', completed: false },
            { name: 'Прочитать книгу', completed: true }
        ];
    }
}

customElements.define('task-list', TaskList);
<ul>
    <li s:for="task in tasks" s:unless="task.completed">
        {{task.name}}
    </li>
</ul>

В этом примере в список попадут только незавершённые задачи. s:unless проверяет свойство completed каждого объекта массива.

Вложенные конструкции

s:unless может быть вложена в другие директивы s:if, s:for или другие s:unless, что позволяет создавать сложные условные блоки:

<div s:if="showPanel">
    <div s:unless="isAdmin">
        Контент для обычных пользователей
    </div>
</div>
  • Внешний блок рендерится только если showPanel истинно.
  • Внутренний блок рендерится только если isAdmin ложь.

Ограничения и особенности

  1. s:unless не поддерживает логические операторы прямо в атрибуте сложного вида без обёртки в метод или вычисляемое свойство. Например, выражение s:unless="!isLoggedIn || isAdmin" лучше вынести в отдельный метод, чтобы избежать ошибок рендеринга.
  2. Можно использовать вместе с привязкой данных через {{}}, чтобы динамически изменять контент внутри блока.
  3. Директива работает только на элементах, являющихся частью компонента Slim.js, и не применима к обычному HTML вне компонента.

Практические советы

  • Для повышения читаемости кода лучше создавать методы или вычисляемые свойства, возвращающие логическое значение, вместо сложных выражений прямо в атрибуте s:unless.
  • При комбинировании с s:for рекомендуется использовать уникальные ключи элементов для оптимизации рендеринга.
  • Вложенные директивы s:unless помогают создавать более декларативный и чистый код без лишних if в JavaScript.

Пример комплексного использования

class Dashboard extends Slim {
    constructor() {
        super();
        this.user = { name: 'Иван', admin: false };
        this.showNotifications = true;
    }

    isRegularUser() {
        return !this.user.admin;
    }
}

customElements.define('app-dashboard', Dashboard);
<app-dashboard>
    <div s:unless="isRegularUser()">
        Панель администратора
    </div>
    <div s:unless="!showNotifications">
        Уведомления
    </div>
</app-dashboard>
  • Первый блок отображается только для администраторов.
  • Второй блок отображается при включённых уведомлениях.
  • Взаимодействие методов компонента и директив s:unless обеспечивает гибкую и понятную логику рендеринга.