仍在学习骨干,所以请耐心等待;
我正在尝试将一个带有空白字段的新模型添加到视图中,但我创建的模板有很多
<input value="<%= some_value %>" type="whatever" />
在获取数据时工作得非常好,它会填充它并且一切顺利。当我想创建一个新的(空白)渲染视图时,会出现问题,它给了我
Uncaught ReferenceError: some_value is not defined
我可以设置defaults
(我已经在db中有一些默认值),但这意味着用空格键入40多个;有没有更好的方法处理这个?
我正在摆弄下划线模板本身,尝试像<%= if(some_value != undefined){ some_value } %>
这样的东西,但这看起来有点麻烦。
答案 0 :(得分:24)
将模板数据传递到包装器对象中。缺少属性访问不会引发错误:
所以,而不是:
var template = _.template('<%= foo %><%= bar %>');
var model = {foo:'foo'};
var result = template(model); //-> Error
尝试:
var template = _.template('<%= model.foo %><%= model.bar %>');
var model = {foo:'foo'};
var result = template({model:model}); //-> "foo"
答案 1 :(得分:11)
实际上,您可以在模板中使用arguments
:
<% if(!_.isUndefined(arguments[0].foo)) { %>
...
<% } %>
答案 2 :(得分:10)
否,强>
由于下划线模板的实现方式,没有实际的修复。
请参阅this discussion:
我担心这只是with(){}在JS中的工作方式。如果未声明变量,则为ReferenceError。我们无能为力,同时保留了其余的模板行为。
你可以完成你正在寻找的东西的唯一方法是用另一个对象包装对象,如建议的其他答案,或者设置默认值。
答案 3 :(得分:5)
如果您检查生成的模板函数的源代码,您将看到如下内容:
with (obj||{}) {
...
// model property is used as variable name
...
}
这里发生了什么:首先JS尝试在“obj”中找到你的属性,这是模型(更多关于with语句)。在“obj”范围中找不到此属性,因此JS遍历全局范围并最终抛出异常。
因此,您可以直接指定范围来修复:
<input value="<%= obj.some_value %>" type="whatever" />
至少它对我有用。
答案 4 :(得分:3)
实际上,您可以像初始对象属性一样访问变量。
如果您将调试器激活到模板中,您可以找到包含所有数据的变量“obj”。
因此,您应该写<%= title %>
<%= obj.title %>
答案 5 :(得分:0)
lodash,一个下划线替代品,提供了一个内置解决方案的template功能。它有一个选项可以将数据包装在另一个对象中以避免使用&#34;导致错误的声明。
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;
// }
答案 6 :(得分:0)
一个非常简单的解决方案:您可以确保数据收集已规范化,即每个对象中都存在所有属性(如果未使用,则为空值)。这样的功能可以提供帮助:
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
答案 7 :(得分:0)
您可以通过向模型添加功能并在模板中使用它来进一步抽象@Dmitri的答案。
例如:
型号:
new Model = Backbone.Model.extend({
defaults: {
has_prop: function(prop) {
return _.isUndefined(this[property]) ? false : true;
}
}
});
模板:
<% if(has_prop('property')) { %>
// Property is available
<% } %>
正如他的回答中的评论所暗示的那样,这是更加可扩展的。