JSViews 和 Materialize 下拉按钮的问题
Issue with JSViews and Materialize Dropdown Button
我在使用带有 JSViews 和 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}}
如果您单击 运行 之后的按钮,它会很好地打开下拉菜单。如果您 select 一个未设置的选项(即将完成按钮设置为未完成),它会更新 UI,但是当 ul 从 DOM 中删除时,单击它再次不显示下拉。只有更新的按钮会受到影响。
谁能看出我错在哪里?
看起来 Materialise 克隆了 ul 并在每个激活器之后插入了一个副本。最初只有一个激活器(因为另一个 {^{if}}
表达式是假的,所以它的内容是空的)——并且克隆的 ul 被放置在它旁边的 {^{if}}
块中。
当您单击切换状态时,{^{if}}
的内容将被删除,而其他 {^{if}}
的内容将被呈现。但是第二个激活器(<a>
标签)还没有 'activated',因此没有关联的 <ul>
。
如果您打算将 Materialize 与 JsViews 一起使用,那么您必须处理 Materialize 可能进行的 DOM 操作,这可能会破坏 JsViews 数据 linking。拥有两个操作相同 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>
更新:
响应 'inline-block' 与 'block' 的 grayson 的 Materialize 相关问题,
这里有几个选择:
你可以data-link直接到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'}" ...>
Boris 的回答是这个问题的正确答案,正如您显然期望的那样,但是,我想补充一点可能对处于这种情况的任何人有所帮助的内容。
JSViews 非常聪明并且使用可见绑定,它似乎尝试识别元素的类型,因此在锚标记的情况下它使用 display:inline,而对于 div它使用 display:block
在实现(和 bootstrap)的情况下,btn class 将显示设置为内联块,因此使用可见绑定并非在所有情况下都按预期工作。
在我的例子中,因为这确实是一个按钮而不是 link,我将锚标记更改为按钮标记,因为这是一个块元素,所以它工作得很好。
这不是一个理想的解决方案,就我而言,我可能有 30 个按钮,有 5 个选项,这意味着 DOM 充满了很多额外的隐藏标签,但直到我想出一个更好的解决方案,使用 {^{if...,它有效。
我在使用带有 JSViews 和 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}}
如果您单击 运行 之后的按钮,它会很好地打开下拉菜单。如果您 select 一个未设置的选项(即将完成按钮设置为未完成),它会更新 UI,但是当 ul 从 DOM 中删除时,单击它再次不显示下拉。只有更新的按钮会受到影响。
谁能看出我错在哪里?
看起来 Materialise 克隆了 ul 并在每个激活器之后插入了一个副本。最初只有一个激活器(因为另一个 {^{if}}
表达式是假的,所以它的内容是空的)——并且克隆的 ul 被放置在它旁边的 {^{if}}
块中。
当您单击切换状态时,{^{if}}
的内容将被删除,而其他 {^{if}}
的内容将被呈现。但是第二个激活器(<a>
标签)还没有 'activated',因此没有关联的 <ul>
。
如果您打算将 Materialize 与 JsViews 一起使用,那么您必须处理 Materialize 可能进行的 DOM 操作,这可能会破坏 JsViews 数据 linking。拥有两个操作相同 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>
更新:
响应 'inline-block' 与 'block' 的 grayson 的 Materialize 相关问题, 这里有几个选择:
你可以data-link直接到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'}" ...>
Boris 的回答是这个问题的正确答案,正如您显然期望的那样,但是,我想补充一点可能对处于这种情况的任何人有所帮助的内容。
JSViews 非常聪明并且使用可见绑定,它似乎尝试识别元素的类型,因此在锚标记的情况下它使用 display:inline,而对于 div它使用 display:block
在实现(和 bootstrap)的情况下,btn class 将显示设置为内联块,因此使用可见绑定并非在所有情况下都按预期工作。
在我的例子中,因为这确实是一个按钮而不是 link,我将锚标记更改为按钮标记,因为这是一个块元素,所以它工作得很好。
这不是一个理想的解决方案,就我而言,我可能有 30 个按钮,有 5 个选项,这意味着 DOM 充满了很多额外的隐藏标签,但直到我想出一个更好的解决方案,使用 {^{if...,它有效。