【问题标题】:Python and angular disagree on variable valuePython和角度不同意变量值
【发布时间】:2016-04-30 18:23:39
【问题描述】:

所以,为了恰当地构建这个框架,我在这里继承了一个代码库,但我对 Angular 没有深入的了解。基本上有一个应用程序可以根据数据库导入是否完成来显示或隐藏加载 gif。

尽管出于某种原因,尽管数据集导入已完成,但 angular 无法识别它。下面的简化代码示例:

<h4>Status
    <small ng-hide="dataset.failed">{{ dataset.status }}</small>
    <img class="pull-right" ng-hide="(dataset.import_complete || dataset.failed)" src="/url" height="12">
</h4>
    <span>{{ dataset.import_complete }}</span>

我为调试目的添加的 span,但实际上 span 显示 True,而上面的 img 标签仍在显示。这意味着 Angular 正在将 dataset.import_complete || dataset.failed 评估为 False

为什么会发生这种情况?任何有助于调试此行为的建议将不胜感激。

更新: 我认为这里的想法是这里发生了一些错误的类型检查。具体来说,以下似乎是正确的:

# Always evaluates to True, regardless of import_complete
dataset.import_complete == True
# Always evaluates to False, again, regardless of import_complete
dataset.import_complete == 'True'
# result is bool, as it should be, making this only more baffling
type(dataset)

另外,这里有一点后端,但可能不是很有帮助:

@route(bp, '/dataset/<int:dataset_id>', methods=["GET", "POST"])

def 数据集(dataset_id): """返回数据集管理页面"""

dataset = Dataset.query.get_or_404(dataset_id)

return render_template(
    'manage/dataset.html',
    dataset=dataset,
)

更多信息,这里是vars(dataset)的输出:

{'import_complete': True, 'failed': False, 'pending_deletion': False}

【问题讨论】:

  • 我怀疑这是 Python 中的这些值没有被序列化为正确 JS 的问题?例如,Python 的 True => JavaScript 的 true
  • 您将ng-hide 设置为字符串(dataset.import_compete || dataset.failed)。您在那里既没有使用 Python 也没有使用 JavaScript 变量。
  • @dirn 真的吗?简要阅读 angularjs 文档似乎暗示我在这里使用了正确的语法。我也在应用程序的许多其他地方使用相同的语法,没有问题。我会改变什么?
  • @dirn 此外,删除引号会导致解析错误。
  • @RyanGonzalez 这似乎是可能的,但我不知道如何调试它。我尝试使用 Batarang 插件,但它不起作用。有什么建议吗?

标签: javascript python angularjs flask jinja2


【解决方案1】:

在 NG 运行之前,Jinja2 是否会对您的表达式进行插值?

不要忘记 Jinja 和 Angular 都使用相同的 {{}} 标记作为它们的语法。

在我看来,您使用 Jinja 来呈现该 HTML,如果该 HTML 也包含您的 AngularJS 代码,那么 {{ expr }} 在 AngularJS 在浏览器上运行之前由 Flask/Jinja 进行插值

我的猜测是你在 HTML 中看到的 True,来自 Jinja2 渲染这个表达式(不是 Angular)

<span>{{ dataset.import_complete }}</span>

至少 key import_complete 是 Angular 应用 $scope 中 dataset JS 对象中的 undefined。 (因为someObject.undefinedKey == 'True' 会给JS 布尔值false

$scope.dataset 对象很可能存在于您的 ng 应用程序中,但似乎 $scope.dataset 不包含密钥 import_complete(要使 ng-hide="dataset.import_complete" 工作,您需要 $scope.dataset.import_complete明确定义)

如何检查?

要确认实际上是 Jinja2 呈现了上述内容,请尝试通过将其保存为 curlwget 来查看 HTML,您应该会看到它在静态 HTML 中没有带有 &lt;span&gt;{{ dataset.import_complete }}&lt;/span&gt;运行 NG,但使用 &lt;span&gt;True&lt;/span&gt;

如何解决

如果这是真的,那么try adapting more structured way this to your project, by separating the server/API and the client

否则,您可以change the tokens for your angular app to something else 进行快速修复,然后弄清楚如何将变量放入您的$scope(例如,在 Jinja 中渲染 $scope.dataset = {{dataset_json}}; 以将其放入 JS,这是您想要的 hack从长远来看要避免

调试

如果这个&lt;span&gt;{{ dataset.import_complete }}&lt;/span&gt; 显示True 作为输出,这确实表明键import_complete 实际上包含一个带有值"True" 的字符串,而不是JS 布尔值true

我重新审视了你的评论,你说你尝试了一些无济于事的事情

ng-hide="dataset.import_complete == 'True'"

这似乎是可能的,但我不知道如何调试它。

所以我建议你像这样查看dataset 对象的值

&lt;p&gt;{{dataset}}&lt;/p&gt;或者&lt;p&gt;{{dataset | json}}&lt;/p&gt;,那么你可以确定它的价值和类型

您还可以查看浏览器的开发工具 Network 选项卡,了解 Flask 后端已发送回 AngularJS 的内容。

【讨论】:

  • 感谢您的想法!因此, import_complete 实际上是 True,但不是字符串。我不确定这里的角度方面是如何处理类型的,但正如发布的那样,== 'True' 的计算结果为false。但是,当删除引号时,它的计算结果为true。似乎与@RyanGonzalez 的建议非常一致。对这些类型发生了什么有任何想法?
  • 哦,另外,为了澄清为什么目前不接受这一点,出于某种原因,即使 dataset.import_complete 为 False,== True 也为真。我......我真的不知道这里发生了什么,但这似乎是一些可怕的类型转换巫毒。无论如何都会在几分钟内接受,但如果您能对此有所了解,我们将不胜感激。
  • 我也很困惑,但如果你挖得够多,我相信会有一个解释。例如JS 中的typeof dataset.import_complete 是什么?无论如何,看看它在 HTTP 中发送了什么?例如在浏览器网络选项卡中?
  • 例如据推测,AngularJS 通过 API '/dataset/123' 提取数据,在 AngularJS 接收数据时查看该数据是有帮助的(不要用type(x) 探测它的 Python 端),但探测它的 JS 端,也许也是浏览器的开发工具网络标签
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-21
  • 1970-01-01
  • 2015-03-16
  • 2019-03-10
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多