在Underscore模板中检查未定义变量

19

我在模板中展示libraryPrep对象的模态视图,就像这样:

if (_.isUndefined(this.libraryPreps)) {
                this.$el.html(this.template({  }));
            } else {
                this.$el.html(this.template({ libraryPreps: this.libraryPreps.toJSON() }));
            }

当我有一个libraryPreps对象时,else语句就会起作用。在我的模板中,我像这样使用它:

<select id="libraryPreps" >
                    <%  if (!_.isUndefined(libraryPreps)) { %>
                    <% _.each(libraryPreps, function (libraryPrep) { %>
                    <option value="<%=libraryPrep.id%>"><%= libraryPrep.name %></option>
                    <% }); %>
                    <% } %>
                </select>
当我没有 libraryPreps 对象时,我的模板不会渲染,并且控制台会报错说 libraryPreps 未定义。我在模板中是否错误地检查了 undefined?我感觉在我的 backbone 模态视图中以同样的方式进行了检查,但是出现在实际模板中时就好像不起作用了。我的模板标记是否正确?谢谢。
3个回答

31

如果你将变量传递给函数,它会被计算并抛出错误,因为没有这样的变量。相比之下,在你的backbone视图中,你正在访问对象的一个属性,这总是有效的(如果不存在具有该名称的属性,则返回undefined值)。

相反,你必须在其上使用typeof运算符,即使对于未声明的变量也可以使用(请参阅variable === undefined vs. typeof variable === "undefined"JavaScript check if variable exists (is defined/initialized)):

<select id="libraryPreps"><%
    if (typeof libraryPreps !== "undefined") {
        _.each(libraryPreps, function (libraryPrep) { %>
            <option value="<%=libraryPrep.id%>"><%= libraryPrep.name %></option><%
        });
    }
%></select>

要在您的模板中使用_.isUndefined,您需要在模板中显式地将该值提供。根据文档

默认情况下,template通过with语句将数据值放置在局部范围内。但是,您可以使用variable设置指定一个单独的变量名称。这可以显著提高模板呈现速度。

_.template("Using 'with': <%= data.answer %>", {answer: 'no'}, {variable: 'data'});
=> "Using 'with': no"
因此,您可以编写如下的模板:
 <% if (!_.isUndefined(data.libraryPreps)) { %> …
 <% if ("libraryPreps" in data) { %> …

0

我知道这涉及到一个旧的线程。但是这个问题仍然存在。

我为自己的堆栈创建了一个解决方案。可能对其他程序员有用。

此代码检查变量是否未定义或为空。如果变量未定义或为空,则返回变量名称。(使用模板语法)。

此更改已针对underscorejs v1.6.0进行了测试。通过轻微更改,它将适用于1.9.1。进一步查看Lodash。这将需要进行轻微调整!

在underscore的dev构建中:

v1.6.0规则:1239

更新版本规则:1575

旧代码:

if (escape) {
  source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
  source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
  source += "';\n" + evaluate + "\n__p+='";
}

新代码:

if (escape) {
    source += "'+\n((typeof " + escape + " === \"undefined\" || " + escape + " === null) ? \"<%-" + (escape.toString()) + "%>\": _.escape(" + escape + "))+\n'";
}
if (interpolate) {
    source += "'+\n((typeof " + interpolate + " === \"undefined\" || " + interpolate + " === null) ? \"<%=" + (interpolate.toString()) +"%>\":" + interpolate + ")+\n'";
}
if (evaluate) {
    source += "';\n" + evaluate + "\n__p+='";
}


0
我遇到了类似的问题,我找到了以下解决方案:
不要使用:`if (typeof libraryPreps !== "undefined") {`
而是使用:`if (!_.isUndefined(obj.libraryPreps)) {`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接