【问题标题】:Why is data-bind: enable only working in some cases?为什么 data-bind: enable 仅在某些情况下有效?
【发布时间】:2019-04-04 21:51:26
【问题描述】:

当 $root.questions.editQuestionDialog.question().canBeDeleted 为真时,我尝试启用一些按钮。这仅在某些情况下有效。对于文件末尾的按钮,表达式始终为 false,即使在我检查属性时它设置为 true。

<div id="headerContent" style="display: none" data-bind="visible: menu.isMenuActive('Questions')">
    <fieldset data-bind="with: questions">
        <legend>Questions <span data-bind="text: headerName"></span></legend>
        <div class="alert alert-info" data-bind="visible: $parent.blockId == 0">
            You must save before you can add questions
        </div>
        <div data-bind="visible: $parent.blockId > 0">
            <button class="btn btn-info" data-bind="click: addQuestion, enable:writeEnabled">Add Question</button>
            <div class="control-group">

                <div data-bind="sortable: {data:groups, beforeMove:$root.questions.allowGroupDrop, afterMove : $root.questions.saveGroupOrder}" class="pointer">
                    <div>
                        <h1><i class="icon-move topMargin10"></i>&nbsp;<span data-bind="text:number() + '. ' + name()"></span></h1>
                        <div data-bind="if:questions">
                            <table >
                            <tbody data-bind="sortable: {data:questions,  afterMove : $root.questions.saveOrder,  beforeMove: $root.questions.allowQuestionDrop, options : {handle : '.sortableHandle', cursor: 'move'} }">
                            <tr class="items">
                            <td class="sortableHandle moveCursor"  width="770px" >
                            <!-- <label data-bind="text: ko.toJSON($data, null, 2)"></label> -->
                            <i class="icon-move"></i>&nbsp;
                            <span data-bind="style: { textDecoration:disabled() ? 'line-through' : 'normal' }, click:$root.questions.editQuestion, text: $parentContext.$index()+1 + '.' + (order()+1) + '. ' + shortText()"></span>

                            <button class="btn btn-danger btn-mini right" style="float:right; width:48px; text-align: center;"
                            data-bind="visible:$data.canBeDeleted() && $root.questions.writeEnabled, click: $root.questions.deleteQuestion">Delete</button>
                            <button class="btn btn-warning btn-mini right" style="float:right; width:48px; text-align: center;"
                            data-bind="visible:$data.canBeDisabled() && $root.questions.writeEnabled, click: $root.questions.disableQuestion">Disable</button>
                            <button class="btn btn-success btn-mini right" style="float:right; width:48px; text-align: center;"
                            data-bind="visible:$data.canBePublished() && $root.questions.writeEnabled, click: $root.questions.publishQuestion">Publish </button>

                            <!-- ko foreach:options-->
                            <div class="left" style="margin-left:50px;margin-top:2px" data-bind="if:subQuestion.text">
                            <i class="icon-angle-right"></i>&nbsp;<span data-bind="text: subQuestion.text()"></span>
                            </div>
                            <!-- /ko-->
                            </td>
                            </tr>
                            </tbody>
                            </table>
                        </div>
                    </div>
                </div>

            </div>
        </div>
    </fieldset>

    <div class="hidden" data-bind="jqdialog : {title : $root.questions.editQuestionDialog.questionIsDisabled() || !$root.questions.writeEnabled()  ? 'View Question' : 'Edit Question', trigger: questions.editQuestionDialog.isOpen, options: {width:880, position: ['center',180]}}">
    <div class="control-group" data-bind="if: $root.questions.editQuestionDialog.question">
    <form style="padding-bottom: 15px;">
    <div data-bind="if: $root.questions.editQuestionDialog.question">
    <div class="control-group" data-bind="with:questions, visible: $root.questions.editQuestionDialog.question().parentOption == null ">
    <div class="controls-row">
    <label class="span10 wellLabel">Question Group</label>
    </div>

    <div class="controls controls-row">
    <table>
    <tr>
    <td>
    <select data-bind="visible: (!editQuestionDialog.addGroupIsActive() && !editQuestionDialog.questionIsDisabled()) , value : editQuestionDialog.question().questionGroupId,
    options: groups,
    optionsText: 'name',
    optionsValue : 'id'"></select>
    <input type="text" data-bind="visible:editQuestionDialog.addGroupIsActive() && !editQuestionDialog.questionIsDisabled(), textInput:editQuestionDialog.newGroupName, hasFocus:editQuestionDialog.addGroupHasFocus, event: { keyup: editQuestionDialog.inputnewGroupkeyUp }" />
    <input type="text" disabled data-bind="visible:!editQuestionDialog.addGroupIsActive() && editQuestionDialog.questionIsDisabled(), value:editQuestionDialog.groupName()" />
    </td>
    <td>
    <label class="btn btn-info" data-bind="visible: !editQuestionDialog.addGroupIsActive() && !editQuestionDialog.questionIsDisabled() , click:editQuestionDialog.addGroup" type="button">Add new group</label>

    <label class="btn btn-primary" data-bind="visible:editQuestionDialog.addGroupIsActive , click:editQuestionDialog.saveGroup">Save Group</label>
    <label class="btn btn-danger" data-bind="visible:editQuestionDialog.viewCancel, click:editQuestionDialog.closeAddGroup">Cancel</label>
    </td>
    </tr>
    </table>
    </div>
    </div>
    <div data-bind="visible:questions.editQuestionDialog.question().questionGroupId">
    <div data-bind="if:questions.editQuestionDialog.question().parentOption">
    <div class="well">
    <span class="label label-info">Sub question</span>
    <ul class="breadcrumb">
    <li><a href="#" data-bind="click: questions.editQuestionDialog.openParentQuestion, text:questions.editQuestionDialog.question().parentOption.question.order()+1 + '. ' + questions.editQuestionDialog.question().parentOption.question.text() "></a></li>
    <li>/</li>
    <li> <span data-bind=" text:questions.editQuestionDialog.question().parentOption.text()"></span></li>
    </ul>
    </div>
    </div>
    <div class="controls controls-row">
    <label class="span7 wellLabel">Question</label>
    <label class="span3 wellLabel">Required</label>
    </div>

    <div class="controls controls-row">
    <input type="text" id="editQuestiontext" class="input-medium span7" data-bind="textInput: $root.questions.editQuestionDialog.question().text, enable:!$root.questions.editQuestionDialog.questionIsDisabled() && $root.questions.editQuestionDialog.question().canBeDeleted" maxlength="300" />
    <select class="span3" data-bind="enable:!$root.questions.editQuestionDialog.questionIsDisabled() && $root.questions.editQuestionDialog.question().canBeDeleted, options: $root.questions.editQuestionDialog.isCorrectOptions, optionsText: 'text', optionsValue: 'value', value:$root.questions.editQuestionDialog.question().isRequired"></select>
    </div>

    <div class="controls controls-row">
    <label class="span10 wellLabel">Type of question</label>
    </div>

    <div class="controls-row" data-bind="disable:$root.questions.editQuestionDialog.questionIsDisabled()">
    <div id=questionTypeChoice class="btn-group" data-bind="with:$root.questions.editQuestionDialog">
    <button class="btn" type="button" data-bind="click:function(){setQuestionType(2);}, css :{'btn-primary' :question().type() == 2}">Yes/No</button>
    <button class="btn"  type="button" data-bind="click:function(){setQuestionType(1);},css :{'btn-primary' : question().type() == 1}">Free text</button>
    <button class="btn" type="button" data-bind="click:function(){setQuestionType(3);},css :{'btn-primary' : question().type() == 3}">Single choice</button>
    <button class="btn" type="button" data-bind="click:function(){setQuestionType(4);},css :{'btn-primary' : question().type() == 4}">Multi choice</button>
    </div>
    </div>
    </div>
    <div data-bind="visible: $root.questions.editQuestionDialog.showOptions">
    <div class="controls controls-row">
    <label class="wellLabel span10">Options</label>
    </div>
    <div class="controls controls-row">
    <table class="table">
    <thead>
    <tr class="primary">
    <th>Text</th>
    <th>Is correct</th>
    <th colspan="3">Points</th>
    </tr>
    </thead>
    <tbody data-bind="visible: $root.questions.editQuestionDialog.question().type() > 2">
    <tr class="success">
    <td class="span4">
    <input type="text" class="span5"  data-bind="enable: !$root.questions.editQuestionDialog.questionIsDisabled() && $root.questions.editQuestionDialog.question().canBeDeleted, textInput:$root.questions.editQuestionDialog.newOption.text, hasFocus:$root.questions.editQuestionDialog.newOption.hasFocus" />
    </td>
    <td class="span2">
    <select class="span1" data-bind="enable:!$root.questions.editQuestionDialog.questionIsDisabled() && $root.questions.editQuestionDialog.question().canBeDeleted, options: $root.questions.editQuestionDialog.isCorrectOptions, optionsText : 'text', optionsValue:'value', value :$root.questions.editQuestionDialog.newOption.isCorrect "></select>
    </td>
    <td class="span2">
    <select class="span1" data-bind="enable:!$root.questions.editQuestionDialog.questionIsDisabled() && $root.questions.editQuestionDialog.question().canBeDeleted, options:$root.questions.editQuestionDialog.pointValues, value:$root.questions.editQuestionDialog.newOption.point"></select>
    </td>

    <td class="span2">
    <button class="btn btn-primary" data-bind="visible: !$root.questions.editQuestionDialog.questionIsDisabled(), click: $root.questions.editQuestionDialog.addNewOption, enable:$root.questions.editQuestionDialog.newOption.text().length > 0">Add</button>
    </td>


    </tr>
    </tbody>
    <div disabled>

    <tbody id="dataGrid" data-bind="foreach: $root.questions.editQuestionDialog.optionsForType">

    <tr  class="sortable-bulk moveCursor", draggable="true" data-bind="disable:$root.questions.editQuestionDialog.questionIsDisabled(), event:{drop: function(data,e) {$root.questions.editQuestionDialog.doOptionDrop(e,data);},
    dragover:function(data,e) {$root.questions.editQuestionDialog.doAllowOptionDrop(e,data);},
    dragleave:function(data,e) {$root.questions.editQuestionDialog.doDragOptionLeave(e,data);},
    dragstart:function(data,e) {return $root.questions.editQuestionDialog.doOptionDrag(e,data);}}">
    <td class="span4" >
    <div>
    <div>
    <input  id="optText" onclick="this.focus(); this.blur(); this.focus();" type="text" class="span5" data-bind="enable: !$root.questions.editQuestionDialog.questionIsDisabled() && $root.questions.editQuestionDialog.question().canBeDeleted, textInput:text"/></td>
    </div>
    </div>
    <td class="span2">
    <select class="span1" data-bind="enable: !$root.questions.editQuestionDialog.questionIsDisabled() && $root.questions.editQuestionDialog.question().canBeDeleted, options: $root.questions.editQuestionDialog.isCorrectOptions, optionsText : 'text', optionsValue:'value', value :isCorrect, event : {change : $root.questions.editQuestionDialog.isCorrectHasChanged}"></select>
    </td>
    <td class="span2">
    <select class="span1" data-bind="enable: !$root.questions.editQuestionDialog.questionIsDisabled() && $root.questions.editQuestionDialog.question().canBeDeleted, options:$root.questions.editQuestionDialog.pointValues, value:point"></select>
    </td>
    <td class="span4">
    <button class="btn btn-danger" data-bind="click: $root.questions.editQuestionDialog.removeOption, visible: $root.questions.editQuestionDialog.question().type() > 2 && !$root.questions.editQuestionDialog.questionIsDisabled()">Remove</button>
    <button class="btn btn-info" data-bind="visible : $root.questions.editQuestionDialog.question().parentOption == null && $root.questions.editQuestionDialog.question().type() != 4 && !$root.questions.editQuestionDialog.questionIsDisabled(), click: $root.questions.editQuestionDialog.addSubQuestion, text: subQuestion.text() != null ? 'Edit sub question' : 'Create sub' ">Sub question</button>
    <button class="btn btn-info" data-bind="visible : $root.questions.editQuestionDialog.question().parentOption == null && $root.questions.editQuestionDialog.question().type() != 4 && $root.questions.editQuestionDialog.questionIsDisabled() && subQuestion.text() != null , click: $root.questions.editQuestionDialog.addSubQuestion, text: subQuestion.text() != null ? 'Show sub question' : null ">Sub question</button>

    </td>
    </tr>
    </tbody>
    </div>
    </table>
    </div>
    </div>
    </div>

    </form>
    </div>
<div>
    <button style="margin: 0px 5px 0px 0px" class="btn pull-right" data-bind="click: questions.editQuestionDialog.close">Close</button>
    <button style="margin: 0px 5px 0px 0px" class="btn btn-warning pull-right" data-bind="click: questions.editQuestionDialog.clearQuestion, enable: $root.questions.editQuestionDialog.question().canBeDeleted">Clear</button>
    <button style="margin: 0px 5px 0px 0px" class="btn btn-info pull-right" data-bind="click: questions.editQuestionDialog.saveQuestion, enable:questions.editQuestionDialog.questionIsValid && $root.questions.editQuestionDialog.question().canBeDeleted">Save</button>
</div>

</div>
</div>

代码是同一文件中的所有代码,表达式在所有其他地方都有效,但文件底部的“保存”和“清除”按钮除外。可能是什么问题呢?您是否需要为 data-bind: visible 和 enable 编写不同的表达式?

【问题讨论】:

  • $root.questions.editQuestionDialog.question().canBeDeleted 的值是多少?它是一个普通的 JS 值还是一个可观察/计算的值?因为如果它不是可观察的,KO 将不知道何时重新评估它。
  • 我认为这是一个可观察到的 KO。我也在代码中发现了这一点。 self.getNewQuestion = function() { var q = ko.mapping.fromJS(json.emptyQuestion); q.isRequired = ko.observable(true); q.canBeDisabled=ko.observable(false); q.canBeDeleted=ko.observable(true); q.canBePublished=ko.observable(true);返回q; };
  • 好的,所以enable: $root.questions.editQuestionDialog.question().canBeDeleted 应该在我记得的情况下工作 KO(有一段时间没有使用它了)。它将直接绑定到可观察对象。 questions.editQuestionDialog.questionIsValid &amp;&amp; $root.questions.editQuestionDialog.question().canBeDeleted 是另一回事——因为它不是一个单一的属性,KO 应该以不同的方式评估该表达式。但我不希望这总是false
  • questions.editQuestionDialog.questionIsValid 正确吗?它不像其他值那样在开头有$root
  • 一开始是否使用 $root 似乎并不重要。

标签: javascript knockout.js


【解决方案1】:

我通过将表单内的按钮向上移动几行来解决这个问题。不太确定为什么会这样,但我猜它与某人所说的绑定有关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-17
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    相关资源
    最近更新 更多