【问题标题】:Issue with JSViews and Materialize Dropdown ButtonJSViews 和 Materialize 下拉按钮的问题
【发布时间】:2017-08-12 14:42:27
【问题描述】:

我在使用带有 JSView 和 Materialize 下拉按钮的链接模板时遇到问题。

第一次渲染视图,它工作正常,但是一旦我观察到更新按钮的状态,链接到按钮的 ul 标记就会从 DOM 中删除。

我在 JSFiddle 上创建了一个测试用例:here

<script id="test_template" type="text/x-jsrender">
{^{for tasks}}
<div class="dropdown change-state" style="display: block">
    {^{if Status == 0}}
        <a href="#" class="completed-state-box dropdown-button btn btn-flat red" data-constrainwidth="false" data-activates='review_status_dropdown-{{:Id}}'>NOT COMPLETE</a>
    {{/if}}

    {^{if Status == 1}}
        <a href="#" class="completed-state-box dropdown-button btn btn-flat green" data-constrainwidth="false" data-activates='review_status_dropdown-{{:Id}}'>COMPLETE</a>
    {{/if}}

    <ul id="review_status_dropdown-{{:Id}}" class="dropdown-content">
        <li><a class="state-change-button" href="#" data-value="0">NOT COMPLETE</a></li>
        <li><a class="state-change-button" href="#" data-value="1">COMPLETE</a></li>
    </ul>

</div>

{{/for}}

如果您在运行后单击一个按钮,它会很好地打开下拉菜单。如果您选择未设置的选项(即,将 COMPLETED 按钮设置为 NOT COMPLETE),它会更新 UI,但随着 ul 从 DOM 中移除,再次单击它不会显示下拉菜单。只有更新的按钮会受到影响。

谁能看出我哪里出错了?

【问题讨论】:

    标签: materialize jsviews


    【解决方案1】:

    看起来 Materialize 克隆了 ul 并在每个激活器之后插入了一个副本。最初只有一个激活器(因为另一个 {^{if}} 表达式为假,因此其内容为空) - 克隆的 ul 被放置在它旁边的 {^{if}} 块内。

    当您单击以切换状态时,该{^{if}} 的内容将被删除,而其他{^{if}} 内容将被呈现。但是第二个激活器(&lt;a&gt; 标签)尚未被“激活”,因此没有关联的&lt;ul&gt;

    如果您打算将 Materialize 与 JsViews 一起使用,那么您必须处理 Materialise 可能会进行 DOM 操作,这可能会破坏 JsViews 数据链接。拥有两个同时操作同一个 DOM 的框架可能会导致冲突或冲突。

    在这种情况下,您可以使用visible 绑定而不是{^{if}} 来解决问题:

    <div class="dropdown change-state" style="display: block">
      <a href="#" data-link="visible{:Status==0}" class="completed-state-box dropdown-button btn btn-flat red" data-constrainwidth="false" data-activates='review_status_dropdown-{{:Id}}'>NOT COMPLETE</a>
      <a href="#" data-link="visible{:Status==1}" class="completed-state-box dropdown-button btn btn-flat green" data-constrainwidth="false" data-activates='review_status_dropdown-{{:Id}}'>COMPLETE</a>
      <ul id="review_status_dropdown-{{:Id}}" class="dropdown-content">
        <li><a class="state-change-button" href="#" data-value="0">NOT COMPLETE</a></li>
        <li><a class="state-change-button" href="#" data-value="1">COMPLETE</a></li>
      </ul>
    </div>
    

    更新:

    针对 grayson 的“inline-block”与“block”的 Materialize 相关问题, 这里有几个选择:

    您可以直接将数据链接到 CSS 显示属性,并指定要切换的值:

    <a data-link="css-display{:Status==1?'inline-block':'none'}" ...>
    

    或者您可以创建一个自定义标签来满足您的需求:

    $.views.tags("show", {
      render: function(val) {
        return val ? "inline-block" : "none"
      },
      attr: "css-display"
    });
    

    然后写:

    <a data-link="{show Status==0}" ...>
    

    你甚至可以这样做:

    $.views.tags("show", {
      render: function(val, type) {
        return val ? type||"inline-block" : "none"
      },
      attr: "css-display"
    });
    

    然后写

    <a data-link="{show Status==0}" ...>
    

    <foo data-link="{show Status==0 'block'}" ...>
    

    【讨论】:

    • 这在使用 Visibilty 时不太有效,因为它将显示设置为“内联”,而不是元素在我的实际代码中需要的“内联块”或“块”。像往常一样,这是一个很棒的答案,希望能让我朝着正确的方向前进。
    • 这真的很奇怪,因为在小提琴中,它会切换显示内联。有代码更新吗?
    • 似乎是当有超过2个选项时。我在小提琴中加了三分之一:jsfiddle.net/x8Lwmk7n/7 看看效果
    • 鲍里斯,你真了不起。我希望有一天我能掌握你一半的技能。
    【解决方案2】:

    Boris 的回答是这个问题的正确答案,正如您显然期望的那样,但是,我想添加一些可以帮助处于这种情况的任何人的内容。

    JSViews 非常聪明,使用可见绑定,它似乎试图识别元素的类型,所以在锚标记的情况下它使用 display:inline,而对于 div 它使用 display:block

    在物化(和引导)的情况下,btn 类将显示设置为内联块,因此使用可见绑定并非在所有情况下都按预期工作。

    在我的例子中,因为这确实是一个按钮而不是一个链接,所以我将锚标记更改为按钮标记,因为这是一个块元素,它工作得很好。

    这不是一个理想的解决方案,就我而言,我可能有 30 个按钮,有 5 个选项,这意味着在 DOM 中充斥着大量额外的隐藏标签,但在我想出更好的解决方案之前,使用 { ^{如果...,它可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-29
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      • 2017-06-29
      • 2019-04-12
      相关资源
      最近更新 更多