2015-09-05 4 views
2

я нашел короткий фрагмент для шнуровки интерполяции по GitHub и укоротить его на это:Интерполяция по умолчанию, если ключ не существует

var interpolate = function (tmpl, data) { 
    return new Function('data', 'with(data){return \'' + 
     tmpl.replace(/{{\s*(.+?)\s*}}/g, '\'+($1)+\'') + '\';}')(data); 
}; 

Он отлично работает для этого:

interpolate('Hello {{user.name}}!', {user: {name: 'Admin'}}); 
// Hello Admin! 

Но есть два результата я не люблю:

interpolate('Hello {{user.firstname}}!', {user: {name: 'Admin'}}); 
// Hello undefined! 

и это одна:

interpolate('Hello {{user.name}}!', {userinfo: {name: 'Admin'}}); 
// Uncaught ReferenceError: user is not defined(…) 

Есть ли способ изменить отрезанный для использования по умолчанию (пустая строка), если ключ не существует?

UPDATE Теперь я нашел решение для всех моих требований:

function interpolate(tmpl, data, defaultValue, reg) {  
    return tmpl.replace(reg || /{{([^{}]*)}}/g, function(a, b) { 
     try { 
      return new Function('data', ['with(data){return ',b,' || \'',(defaultValue || ''),'\';}'].join(''))(data); 
     } 
     catch(e) { 
      return defaultValue || '';     
     } 
    }); 
} 

interpolate('Existing value: {{user.name}} - global value: {{Date.now()}} - undefined: {{user.age}} - exception: {{dat.haha}}', {user: {name: 'Admin'}}, '?'); 
// "Existing value: Admin - global value: 1441555682168 - undefined: ? - exception: ?" 

Предложения являются Wellcome!

ответ

1

Следующие работы, если у вас есть только один заполнитель в строке:

var interpolate = function(s, data) { 
 
    var RE= /{{\s*(.+?)\s*}}/, 
 
     sp= s.match(RE)[1].split('.'); //example: ['user','name'] 
 

 
    sp.forEach(function(key) { 
 
    data= data[key] || ''; //walk the object, defaulting to null string if undefined 
 
    }); 
 
    
 
    return s.replace(RE, data); 
 
}; 
 

 
console.log(interpolate('Hello {{user.name}}!', {user: {name: 'Admin'}})); 
 

 
console.log(interpolate('Hello {{user.firstname}}!', {user: {name: 'Admin'}})); 
 

 
console.log(interpolate('Hello {{user.name}}!', {userinfo: {name: 'Admin'}}));

К сожалению такие выражения, как {{Date.now()}} dont't работы с это решение

В этом случае вы do необходимо использовать new Function() или eval().

Вы можете добавить оценку короткого замыкания (|| '') в строку объявления функции, чтобы избежать неопределенных свойств объекта, а также try...catch, чтобы избежать ошибок, связанных с ошибками.

В следующем фрагменте функция строка для второго примера заканчивает тем, что-то вроде этого:

with(data) try { 
    return 'Hello '+(user.firstname || "")+'!'; 
} catch(e) { 
    return 'Hello !' 
} 

Snippet:

var interpolate = function (tmpl, data) { 
 
    var f= 'with(data) try{return \'' + 
 
      tmpl.replace(/{{\s*(.+?)\s*}}/g, ('\'+($1 || "")+\'')) + '\';}'+ 
 
     'catch(e) {return \'' + 
 
      tmpl.replace(/{{\s*(.+?)\s*}}/g, '') + "'"+ 
 
     '}'; 
 
    return new Function('data', f)(data); 
 
}; 
 

 
console.log(interpolate('Hello {{user.name}}, it is currently {{Date()}}!', {user: {name: 'Admin'}})); 
 

 
console.log(interpolate('Hello {{user.firstname}}!', {user: {name: 'Admin'}})); 
 

 
console.log(interpolate('Hello {{user.name}}!', {userinfo: {name: 'Admin'}}));

+1

Спасибо, это является правильным ответом на мой вопрос. К сожалению, выражения типа {{Date.now()}} не работают с этим решением, но это не было частью моего вопроса, поэтому я принял ваш ответ. – Martin

+0

Ха, как только я обновил свой ответ, я вижу, что вы нашли свой собственный ответ на проблему. Отличная работа. –

Смежные вопросы