【问题标题】:How to call a function in data-binding when lots of parameters are involved涉及大量参数时如何在数据绑定中调用函数
【发布时间】:2017-02-15 01:56:36
【问题描述】:

目前我的模板中有这个:

  • 方式 1

          <template is="dom-if" if="{{_showCancel(userData.generic.id,info.userId,info._children.gigId.userId,info.accepted,info.cancelled,info.paymentTerms)}}">
    

然后在我的元素中:

  _showCancel: function(viewerUserId,offerUserId,gigUserId, accepted, cancel, paymentTerms) {

    // Offer needs to be accepted and NOT cancelled
    if (!info.accepted || info.cancelled) return false;

    // Gig owner can ALWAYS cancel an offer
    if (viewerUserId == gigUserId ) return true;

    // Offer maker can only cancel if the gig involved pre-payment
    if (viewerUserId == offerUserId && paymentTerms != 'on-day') return true;

    return false;
  },

这个函数的参数太多了吗?

  • 方式 2

我应该只用这样的东西吗:

<template is="dom-if" if="{{_showCancel(userData, info)}}">
  • 方式 3

虽然我想检查它们的子属性是否也发生变化......所以我需要:

<template is="dom-if" if="{{_showCancel(userData, info, userData.*, info.*)}}">
  • 方式 4

但话又说回来,我可能应该只查找属性并像这样使用value 属性:

<template is="dom-if" if="{{_showCancel(userData.*, info.*)}}">

然后函数将是:

_showCancel: function(userDataObs, infoObs) {
  var userData = userDataObs.value;
  var info = infoObs.value;

  if( !userData || !info) return;

  ...

问题:

  • 您是否发现方法 1 到 4 存在任何根本性错误?
  • 方式 1 真的是最好的方法吗? (现在感觉就是这样)
  • 方式 3 是可接受的模式吗?

附录

遇到这种情况我会怎么做:

<paper-button 
  raised 
  hidden$="{{!_showCancel(item.id,userData.config.usersCategories,userData.config.userCategories,userData.config.usersCategories.*)}}"
>
Cancel
</paper-button>

(注意:usersCategoriesArray) 而_showCancel 是:

  _showCancel: function(categoryId, userCategories) {
    for (var k in usersCategories) {
      var $ucat = usersCategories[k];

      if ($ucat.categoryId == categoryId) {
        if ($ucat.status == 'applied' || $ucat.status == 'granted') return true;
      }
    }

    return false;
  },

重点是:我希望既能轻松访问usersCategories,又不想从“奇怪”的数组修饰符等中获取值。那么,这是一个好的模式吗?

【问题讨论】:

  • 补充:如果你想检测数组突变,你需要听&lt;array&gt;.*&lt;array&gt;.splicessee spec)。如果你不喜欢 splicesstrange 修饰符),那么你可以在你的函数中忽略它们。但是您仍然应该同时传递数组和 .*.splices 变量。没有它,更改将无法正确传播。您当前的代码实际上是可以的。除了for/initeration。这不是迭代数组的好方法,使用简单的fori 作为索引。
  • 我最近发现我可以用 for 语句迭代一个数组。我发现它更容易!这有什么问题?
  • 一切都好,我刚刚想通了 :D stackoverflow.com/questions/500504/…

标签: data-binding polymer web-component


【解决方案1】:

方式 1”是正确的。 但是,您应该只引用您需要的变量,并且应该始终按照函数头中定义的方式使用它们。

例如,您使用:

{{_showCancel(userData.generic.id,info.userId,info._children.gigId.userId,info.accepted,info.cancelled,info.paymentTerms)}}

带有以下函数头:

_showCancel: function(viewerUserId,offerUserId,gigUserId, accepted, cancel, paymentTerms).

但是在函数内部,你引用了info.acceptedinfo.cancelled,而你应该使用acceptedcancelled

这是因为在函数内部,引用的值始终是最新的,而通过 this.&lt;variable-name&gt; 引用的变量有时可能包含旧值。

为了让我的回答完整,我还会用其他方式解释某些“问题”。

方式 2:在这里,您只引用整个 Object。这不会通过子属性更改触发调用,因此不会按预期工作。

Way 3Way 4 相似,都是矫枉过正。使用 object.* 表示法,您可以听到 所有 子属性更改,这很可能是您不想要的

tl;博士

使用“Way 1”并使用计算属性使事情变得更简单。

为此,请更改:

<template is="dom-if" if="{{_showCancel(userData.generic.id,info.userId,info._children.gigId.userId,info.accepted,info.cancelled,info.paymentTerms)}}">

收件人:

<template is="dom-if" if="{{isCanceled}}">

并将以下计算属性添加到 Polymer 元素:

isCanceled: {
  type: Boolean,
  computed: '_showCancel(userData.generic.id,info.userId,info._children.gigId.userId,info.accepted,info.cancelled,info.paymentTerms)'
}

您已经定义了_showCancel,所以实际上就是这样。该代码应该与您的“Way 1”示例相同,只有dom-if 更干净。如果您在多次出现时重复使用条件,这将特别有用。

如果您有任何问题,请不要犹豫,添加评论。

【讨论】:

  • 拥有完整的 info.cancelled 是剪切和粘贴代码时留下的拼写错误。感谢您的回答,特别是对于计算属性的想法!!!
  • 感谢您的精彩回答。我接受了……我还添加了一个附录问题。我知道你没有动力去回答,但如果你能回答那就太棒了:D
猜你喜欢
  • 2015-08-02
  • 2020-01-03
  • 2011-05-19
  • 1970-01-01
  • 2016-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多