Translation management

Модели и коллекции для хранения переводов

В Backbone.js ключевым элементом для организации данных являются модели (Backbone.Model) и коллекции (Backbone.Collection). Для управления переводами удобно создать модель Translation, которая будет содержать информацию о ключе перевода, тексте на разных языках и возможных метаданных (например, статус перевода или дату обновления).

var Translation = Backbone.Model.extend({
    defaults: {
        key: '',
        value: {},
        UPDATEdAt: null
    },

    initialize: function() {
        if (!this.get('updatedAt')) {
            this.se t('UPDATEdAt', new Date());
        }
    },

    getTranslation: function(lang) {
        return this.get('value')[lang] || null;
    },

    setTranslation: function(lang, text) {
        var values = _.clone(this.get('value'));
        values[lang] = text;
        this.se t({ value: values, UPDATEdAt: new Date() });
    }
});

var TranslationsCollection = Backbone.Collection.extend({
    model: Translation,

    findByKey: function(key) {
        return this.findWhere({ key: key });
    },

    getTranslation: function(key, lang) {
        var translation = this.findByKey(key);
        return translation ? translation.getTranslation(lang) : null;
    },

    setTranslation: function(key, lang, text) {
        var translation = this.findByKey(key);
        if (translation) {
            translation.setTranslation(lang, text);
        } else {
            this.add(new Translation({ key: key, value: { [lang]: text } }));
        }
    }
});

Ключевые моменты:

  • Модель Translation хранит ключ перевода и объект value с языковыми версиями.
  • Методы getTranslation и setTranslation обеспечивают доступ к конкретной локализации.
  • Коллекция TranslationsCollection упрощает поиск и управление множественными переводами.

Views для отображения и редактирования переводов

Backbone.View позволяет создавать динамические интерфейсы для управления переводами. В типичном случае потребуется список переводов и редактор конкретного перевода.

var TranslationView = Backbone.View.extend({
    tagName: 'div',
    className: 'translation-item',

    template: _.template(
        '<strong><%= key %></strong>: <span class="translation"><%= text %></span>' +
        '<input class="edit" type="text" value="<%= text %>" style="display:none;">' +
        '<button class="edit-btn">Редактировать</button>' +
        '<button class="save-btn" style="display:none;">Сохранить</button>'
    ),

    events: {
        'click .edit-btn': 'edit',
        'click .save-btn': 'save'
    },

    initialize: function(options) {
        this.lang = options.lang;
        this.listenTo(this.model, 'change', this.render);
    },

    render: function() {
        this.$el.html(this.template({
            key: this.model.get('key'),
            text: this.model.getTranslation(this.lang) || ''
        }));
        return this;
    },

    edit: function() {
        this.$('.translation').hide();
        this.$('.edit').show();
        this.$('.edit-btn').hide();
        this.$('.save-btn').show();
    },

    save: function() {
        var newValue = this.$('.edit').val();
        this.model.setTranslation(this.lang, newValue);
        this.$('.translation').show();
        this.$('.edit').hide();
        this.$('.edit-btn').show();
        this.$('.save-btn').hide();
    }
});

Особенности реализации:

  • Используется template для рендеринга ключа и значения перевода.
  • Методы edit и save обеспечивают инлайн-редактирование.
  • Прослушивание событий модели (listenTo) автоматически обновляет интерфейс при изменении данных.

Для списка переводов создается коллекционный View:

var TranslationsListView = Backbone.View.extend({
    initialize: function(options) {
        this.lang = options.lang;
        this.listenTo(this.collection, 'add remove change', this.render);
    },

    render: function() {
        this.$el.empty();
        this.collection.each((translation) => {
            var view = new TranslationView({ model: translation, lang: this.lang });
            this.$el.append(view.render().el);
        });
        return this;
    }
});

Поддержка динамического переключения языков

Для мультиязычного интерфейса необходимо обеспечить возможность смены языка на лету. Это достигается обновлением свойств lang во всех Views и повторным рендерингом.

function switchLanguage(listView, newLang) {
    listView.lang = newLang;
    listView.render();
}

Синхронизация с сервером

Backbone.Model и Backbone.Collection поддерживают методы fetch, save, destroy, что позволяет синхронизировать переводы с сервером через REST API.

var Translation = Backbone.Model.extend({
    urlRoot: '/api/translations',
    defaults: {
        key: '',
        value: {},
        updatedAt: null
    }
});

var TranslationsCollection = Backbone.Collection.extend({
    model: Translation,
    url: '/api/translations'
});

Рекомендации по организации данных:

  • На сервере хранить ключи переводов и объект языковых версий.
  • Для массовых обновлений использовать collection.save() или отдельные endpoint для батчевых операций.
  • Обновление интерфейса должно происходить через события change и sync.

Фильтрация и поиск переводов

Backbone.Collection предоставляет методы filter, findWhere, where, что позволяет реализовать динамический поиск и фильтрацию переводов по ключу, языку или статусу.

var filtered = translationsCollection.filter(function(model) {
    return model.getTranslation('ru') && model.getTranslation('ru').length > 0;
});

Автоматическое обновление интерфейса при изменении данных

Backbone ориентирован на событийную модель, что позволяет:

  • Отслеживать изменения отдельных переводов (change на модели).
  • Отслеживать добавление или удаление переводов (add, remove на коллекции).
  • Обновлять только изменившиеся элементы интерфейса, минимизируя перерисовку.

Интеграция с шаблонизаторами

Для больших проектов можно использовать сторонние шаблонизаторы (например, Handlebars или Mustache), чтобы отделить логику отображения от бизнес-логики управления переводами. Backbone.View предоставляет гибкий механизм для внедрения любых шаблонов через метод render.

Управление версиями переводов

Для сложных систем управления переводами рекомендуется хранить историю изменений в модели:

var Translation = Backbone.Model.extend({
    defaults: {
        key: '',
        value: {},
        history: []
    },

    setTranslation: function(lang, text) {
        var values = _.clone(this.get('value'));
        values[lang] = text;
        var hist = _.clone(this.get('history'));
        hist.push({ lang: lang, value: text, date: new Date() });
        this.se t({ value: values, history: hist });
    }
});

Это позволяет реализовать откат к предыдущим версиям или аудит изменений.

Поддержка асинхронной загрузки переводов

При работе с большим количеством переводов рекомендуется использовать ленивую загрузку (lazy loading) или пагинацию на уровне коллекции:

translationsCollection.fetch({
    data: { page: 1, per_page: 50 },
    success: function() {
        listView.render();
    }
});

Такой подход снижает нагрузку на клиент и ускоряет отрисовку интерфейса.

Итоговая архитектура

  • Model Translation: хранение ключей, значений, истории изменений.
  • Collection TranslationsCollection: управление множеством переводов, поиск, фильтрация.
  • View TranslationView: отображение и редактирование отдельного перевода.
  • View TranslationsListView: список переводов с поддержкой динамического рендеринга и фильтрации.
  • REST-синхронизация: fetch, save, destroy для взаимодействия с сервером.
  • Поддержка мультиязычности: динамическое переключение языков через обновление lang во Views.

Эта структура позволяет построить масштабируемую систему управления переводами на Backbone.js, с гибкой архитектурой, возможностью расширения функционала и интеграции с внешними сервисами.