Подтвердить что ты не робот

Игнорирование undefined данных/варов в шаблоне подчеркивания

Продолжайте учиться с позвоночником, так что несите меня;

Я пытаюсь добавить новую модель с пустыми полями в представление, но созданный мной шаблон имеет целую кучу

<input value="<%= some_value %>" type="whatever" />

Прекрасно работает при извлечении данных, он заполняет его, и все идет хорошо. Проблема возникает, когда я хочу создать новый (пустой) визуализированный вид, он дает мне

Uncaught ReferenceError: some_value is not defined

Я могу установить defaults (я уже делал это для нескольких, которые имеют значения по умолчанию в db), но это означает, что вы можете ввести более 40 из них с пробелами; есть ли лучший способ справиться с этим?

Я возился с самим шаблоном подчеркивания, пытаясь что-то вроде <%= if(some_value != undefined){ some_value } %>, но это также кажется немного громоздким.

4b9b3361

Ответ 1

Нет,

Фактическое исправление для этого невозможно из-за реализации шаблонов подчеркивания.

Смотрите это обсуждение об этом:

Я боюсь, что это просто способ, с помощью которого() {} работает в JS. Если переменная не объявлена, это ReferenceError. Мы ничего не можем с этим поделать, сохраняя при этом остальное поведение шаблонов.

Единственный способ, которым вы можете выполнить то, что вы ищете, - либо обернуть объект другим объектом, как и другим предложенным вами ответом, либо установить настройки по умолчанию.

Ответ 2

Передайте данные шаблона внутри объекта-обертки. Отсутствие доступа к свойствам не приведет к ошибке:

Итак, вместо:

var template = _.template('<%= foo %><%= bar %>');
var model = {foo:'foo'};
var result = template(model); //-> Error

Try:

var template = _.template('<%= model.foo %><%= model.bar %>');
var model = {foo:'foo'};
var result = template({model:model}); //-> "foo"

Ответ 3

Собственно, вы можете использовать arguments внутри вашего шаблона:

<% if(!_.isUndefined(arguments[0].foo)) { %>
       ...
<% } %>

Ответ 4

Если вы проверите исходный код для сгенерированной функции шаблона, вы увидите что-то вроде этого:

with (obj||{}) {
  ...
  // model property is used as variable name
  ...
}

Что происходит здесь: сначала JS пытается найти ваше свойство в "obj", которое является моделью (подробнее о with), Это свойство не найдено в области "obj", поэтому JS проходит вверх и вверх до глобальной области видимости и, наконец, генерирует исключение.

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

<input value="<%= obj.some_value %>" type="whatever" />

По крайней мере, это сработало для меня.

Ответ 5

На самом деле вы можете получить доступ к таким свойствам, как свойства начального объекта.

Если вы активируете отладчик в шаблон, вы можете найти переменную "obj", которая содержит все ваши данные.

Итак, вместо <%= title %> вам следует написать <%= obj.title %>

Ответ 6

lodash, замена подчеркивания, обеспечивает template функцию со встроенным решением. Он имеет возможность обертывать данные другим объектом, чтобы избежать оператора "с", вызывающего ошибку.

Пример использования документации API:

// using the `variable` option to ensure a with-statement isn’t used in the compiled template
var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
compiled.source;
// → function(data) {
//   var __t, __p = '';
//   __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
//   return __p;
// }

Ответ 7

Очень простое решение: вы можете обеспечить нормализацию вашей коллекции данных, то есть все свойства присутствуют в каждом объекте (с нулевым значением, если они не используются). Подобная функция может помочь:

function normalizeCollection (collection, properties) {
  properties = properties || [];
  return _.map(collection, function (obj) {
    return _.assign({}, _.zipObject(properties, _.fill(Array(properties.length), null)), obj);
  });
}

(Примечание: _.zipObject и _.fill доступны в последних версиях lodash, но не подчеркиваются)

Используйте его следующим образом:

var coll = [
  { id: 1, name: "Eisenstein"},
  { id: 2 }
];

var c = normalizeCollection(coll, ["id", "name", "age"]);
// Output =>
// [
//  { age: null, id: 1, name: "Eisenstein" },
//  { age: null, id: 2, name: null }
// ]

Конечно, вам не нужно постоянно трансформировать свои данные – просто вызовите функцию "на лету", когда вы вызываете функцию рендеринга вашего шаблона:

var compiled = _.template(""); // Your template string here
// var output = compiled(data); // Instead of this
var output = compiled(normalizeCollection(data)); // Do this 

Ответ 8

Вы можете абстрактно ответить @Dmitri дальше, добавив функцию в свою модель и используя ее в своем шаблоне.

Например:

Модель:

new Model = Backbone.Model.extend({
    defaults: {
        has_prop: function(prop) {
            return _.isUndefined(this[property]) ? false : true;
        }
    }
});

Шаблон:

<% if(has_prop('property')) { %>
    // Property is available
<% } %>

Как говорится в его ответе, это более расширяемо.