knockoutjs单选按钮检查了protectedobservable的值



感谢您对此进行调查。

我构建了以下示例:http://jsfiddle.net/zm381qjx/5/

这是一个菜单列表生成器。添加菜单时,会弹出一个编辑表单。使用protectedObservable,这样我就可以提交或重置(根据代码)。我遇到的一个问题是,有一个单选按钮列表(用于TypeId),根据值(10=Url,20=Category,30=Page),您可以设置相应的属性(10=Url,20=CategoryId,30=PageId)。

点击单选按钮,如果选择了Url,则应显示另一个文本框(基于urlVisible),以便用户可以输入Url。我添加了一个带有文本的span:TypeId.temp,这样我就可以看到临时值。这是非常不规则的。试着浏览几次。

任何帮助都将不胜感激。

我的HTML

<a class="btn btn-primary" data-bind="click: addMenu">Add Menu</a>
<ul data-bind="foreach: Menus">
    <li><a href="#" data-bind="text: Name, click: editMenu"></a></li>
</ul>
<div class="panel panel-default" data-bind="slideIn: editMenuItem, with: editMenuItem">
    <div class="panel-body">
        <div class="form-group">
            <label for="MenuName">Name: </label>
            <input type="text" id="MenuName" data-bind="value: Name" class="form-control" />
        </div>
        <label class="radio-inline">
            <input type="radio" name="MenuTypeId" value="10" data-bind="checked: TypeId" /> Url
        </label>
        <label class="radio-inline">
            <input type="radio" name="MenuTypeId" value="20" data-bind="checked: TypeId" /> Category
        </label>
        <label class="radio-inline">
            <input type="radio" name="MenuTypeId" value="30" data-bind="checked: TypeId" /> Page
        </label>
        <div class="form-group" data-bind="visible: urlVisible">
            <label for="MenuUrl">Url: </label>
            <input type="text" id="MenuUrl" data-bind="value: Url" class="form-control" />
        </div>
        <br />
        <p>TypeId.temp = <span data-bind="text: TypeId.temp"></span></p>
        <br /><br />
        <input type="button" class="btn btn-success" value="Update" data-bind="click: commit" /> or 
        <a href="#" data-bind="click: reset">Cancel</a>
    </div>
</div>

我的JS:

var vm = null;
//wrapper for an observable that protects value until committed
ko.protectedObservable = function (initialValue) {
    //private variables
    var _temp = ko.observable(initialValue);
    var _actual = ko.observable(initialValue);
    var result = ko.dependentObservable({
        read: function () {
            return _actual();
        },
        write: function (newValue) {
            _temp(newValue);
        }
    });
    //commit the temporary value to our observable, if it is different
    result.commit = function () {
        var temp = _temp();
        if (temp !== _actual()) {
            _actual(temp);
        }
    };
    //notify subscribers to update their value with the original
    result.reset = function () {
        _actual.valueHasMutated();
        _temp(_actual());
    };
    result.temp = _temp;
    return result;
};
ko.bindingHandlers.slideIn = {
    init: function (element) {
        $(element).hide();
    },
    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        if (value) {
            $(element).stop().hide().slideDown('fast');
        } else {
            $(element).stop().slideUp('fast');
        }
    }
};
var Menu = function (Id, Name, TypeId, CategoryId, PageId, Url) {
    var self = this;
    /* Core Properties */
    self.Id = ko.observable(Id);
    self.Name = ko.protectedObservable(Name);
    self.TypeId = ko.protectedObservable(TypeId);
    self.CategoryId = ko.protectedObservable(CategoryId);
    self.PageId = ko.protectedObservable(PageId);
    self.Url = ko.protectedObservable(Url);
    /* Virtual Properties */
    self.urlVisible = ko.computed(function () {
        return self.TypeId.temp() == "10";
    }, self);

    /* Virtual Functions */
    self.editMenu = function (data) {
        if(vm.editMenuItem()) {
            vm.editMenuItem(null);
        }
        vm.editMenuItem(data);
    };
    /* Core Functions */
    self.commit = function () {
        if (self.Name.temp() == '' || self.Name.temp() == null) {
            alert('Please enter a name.'); return;
        }
        self.Name.commit();
        self.TypeId.commit();
        self.CategoryId.commit();
        self.PageId.commit();
        self.Url.commit();
        vm.editMenuItem(null);
    };
    self.reset = function () {
        self.Name.reset();
        self.TypeId.reset();
        self.CategoryId.reset();
        self.PageId.reset();
        self.Url.reset();
        vm.editMenuItem(null);
    };
};
var ViewModel = function() {
    var self = this;
    /* Core Properties */
    self.Menus = ko.observableArray([]);
    /* Virtual Properties */
    self.editMenuItem = ko.observable(null);
    self.addMenu = function(){
        var menu = new Menu(0, "New Menu", "10", 0, 0, "");
        self.Menus.push(menu);
        self.editMenuItem(menu);
    };
};

$(function () {
    vm = new ViewModel();
    ko.applyBindings(vm);
});

如果您将单选按钮绑定更改为

<input type="radio" name="MenuTypeId" value="10" data-bind="checked: TypeId.temp" />

临时id将相应地更改,单选按钮的行为是一致的,但不使用TypeId作为值。

同时protectedObservable绑定单选按钮值也不太好

当您手动单击单选按钮时,TypeId值永远不会更改(因为您没有提交该值),我猜由于单选按钮值永远不会从10更改,因此它无法识别随后手动单击Url单选按钮。

我用一个按钮更新了值,它也在相应地改变;但在随后的单选按钮点击时,它不会从该TypeId中移动值

问题仍然出现在protectedObservable绑定中,但不是简单的observable。

进一步探讨这一想法的代码:http://jsfiddle.net/zm381qjx/101/

相关内容

  • 没有找到相关文章

最新更新