javascript 检查下划线模板中未定义的变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16977178/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 06:38:55  来源:igfitidea点击:

checking for undefined variable in underscore template

javascriptunderscore.js

提问by Crystal

I show a modal view of libraryPrep objects in my template like this:

我在我的模板中显示 libraryPrep 对象的模式视图,如下所示:

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

The else statement works when I have a libraryPreps object. In my template, I use it like this:

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

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

When I don't have a libraryPreps object, I don't get my template to render and I get an error on the console that libraryPreps is undefined. Am I checking for undefined incorrectly in my template? I feel like I'm checking it the same way in my backbone modal view, but for some reason, in my actual template, it doesn't seem to work. Is my template notation correct? Thanks.

当我没有 libraryPreps 对象时,我不会让我的模板进行渲染,并且我在控制台上收到一个错误,提示 libraryPreps 未定义。我是否在模板中错误地检查了 undefined?我觉得我在主干模式视图中以相同的方式检查它,但出于某种原因,在我的实际模板中,它似乎不起作用。我的模板符号是否正确?谢谢。

回答by Bergi

If you're passing the variable to a function, it is getting evaluated and will throw an error as there is no such variable. In your backbone view, in contrast, you're accessing a propertyof an object which will always work (and return the undefinedvalue if no property with that name exists).

如果您将变量传递给函数,它会被求值并且会抛出错误,因为没有这样的变量。相反,在您的主干视图中,您正在访问一个始终有效的对象的属性undefined如果不存在具有该名称的属性,则返回该值)。

Instead, you will have to use the typeofoperator on it, that will even work for undeclared variables (have a look at variable === undefined vs. typeof variable === "undefined"and JavaScript check if variable exists (is defined/initialized)):

相反,您必须在其上使用typeof运算符,这甚至适用于未声明的变量(查看变量 === undefined 与 typeof variable === "undefined"JavaScript 检查变量是否存在(已定义/初始化) )):

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

To use _.isUndefinedin your template, you'd need to make the value explicitly available in the template. From the docs:

_.isUndefined在您的模板中使用,您需要使该值在模板中明确可用。从文档

By default, templateplaces the values from your data in the local scope via the withstatement. However, you can specify a single variable name with the variablesetting. This can significantly improve the speed at which a template is able to render.

_.template("Using 'with': <%= data.answer %>", {answer: 'no'}, {variable: 'data'});
=> "Using 'with': no"

默认情况下,template通过with语句将数据中的值放置在本地范围内。但是,您可以使用variable设置指定单个变量名称。这可以显着提高模板渲染的速度。

_.template("Using 'with': <%= data.answer %>", {answer: 'no'}, {variable: 'data'});
=> "Using 'with': no"

So with that, you can write templates like this:

因此,您可以像这样编写模板:

 <% if (!_.isUndefined(data.libraryPreps)) { %> …
 <% if ("libraryPreps" in data) { %> …

回答by nickel715

I had a similar problem, I found the following solution:

我遇到了类似的问题,我找到了以下解决方案:

Instead of: if (typeof libraryPreps !== "undefined") {

代替: if (typeof libraryPreps !== "undefined") {

Use: if (!_.isUndefined(obj.libraryPreps)) {

利用: if (!_.isUndefined(obj.libraryPreps)) {

回答by Ivo

I know this involves a old thread. But this issue still remaines active.

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

I've created a solution for my own stack. Might be usefull for other programmers.

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

This code checks whether variables are undefined or null. In case variables are undefined or null the variable name is returned. (With template syntax).

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

This change is tested for underscorejs v1.6.0. With minor changes this will work up to 1.9.1. Further looking to Lodash. This will work with minor adjustments!

此更改已针对 underscorejs v1.6.0 进行了测试。稍加改动,这将适用于 1.9.1。进一步寻找 Lodash。这将适用于微小的调整!

In the dev build of underscore on:

在下划线的开发版本中:

v1.6.0 rule: 1239

v1.6.0 规则:1239

Newer versions rule: 1575

较新的版本规则:1575

Old code:

旧代码:

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+='";
}

New code:

新代码:

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+='";
}