简体   繁体   English

如何获得可观察的属性名称KnockoutJS

[英]How to get observable property name KnockoutJS

function Employee() {
    var self = this;
    self.name = ko.observable("John");
}

ko.bindingHandlers.test = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        // implementation
    }
}

<div data-bind="test: name"></div>

Is there a way to get the observable name? 有没有办法获得可观察的名称? not the value of the observable. 不是可观察值。

TIA. TIA。

Update: 更新:

This is the code snippet. 这是代码片段。

function ViewModel() {
    var self = this;
    $.ajax({
       type: type,
       url: url,
       success: function (data) {
           ko.mapping.fromJS(data, {} , self);
       }
    });
    self.item = ko.observable(self.my_item); 
    self.selectedItem = ko.observable();

}

ko.bindingHandlers.item = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        $el = $(element);
        var propName = allBindings().name;
        var val = ko.unwrap(valueAccessor());
        $el.attr("src", val);

        $el.click(function () {
            viewModel.selectedItem(propName); 
        });
    },
    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        $el = $(element);
        var ops = allBindings().name;
        var val = ko.unwrap(valueAccessor());
        $el.attr("src", val);
    }
};

ko.bindingHandlers.selectItem = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        $el = $(element);
        $el.attr("src", valueAccessor());
        $el.click(function () {
            bindingContext.$data.item()[ko.unwrap(bindingContext.$data.selectedItem)](valueAccessor());
        });
    }
};


<img height="25" width="25" data-bind="item: item().img1, name: 'img1'" />
<img height="20" width="20" data-bind="selectItem: '/images/myimage1.png'" />
<img height="20" width="20" data-bind="selectItem: '/images/myimage2.png'" />
<img height="20" width="20" data-bind="selectItem: '/images/myimage3.png'" />

When you click images that has selectItem the first image should replaced its src attribute. 单击具有selectItem的图像时,第一个图像应替换其src属性。 If you have better way to do this please suggest. 如果您有更好的方法来执行此操作,请提出建议。

FYI, the properties inside items observables are link of images. 仅供参考,可观察items内部的属性是图像的链接。

TIA. TIA。

You are getting ahead of yourself with the custom binding. 您将通过自定义绑定超越自己。

The bottom line is: You don't need a custom binding for what you want to do. 最重要的是:您不需要为要执行的操作自定义绑定。 It's easy - if you don't make it complicated: 这很容易-如果您不做复杂的话:

 function loadImages() { // return $.get(url); // mockup Ajax response, in place of a real $.get call return $.Deferred().resolve({ items: [ {height: 20, width: 20, src: 'http://placehold.it/150/30ac17', title: 'image 1'}, {height: 20, width: 20, src: 'http://placehold.it/150/412ffd', title: 'image 2'}, {height: 20, width: 20, src: 'http://placehold.it/150/c672a0', title: 'image 3'} ] }).promise(); } function ImageList() { var self = this; // data self.items = ko.observableArray(); self.selectedItem = ko.observable(); // init loadImages().done(function (data) { ko.mapping.fromJS(data, {}, self); }); } ko.applyBindings(new ImageList()) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script> <div data-bind="with: selectedItem"> <img data-bind="attr: {height: 25, width: 25, src: src}"> </div> <div data-bind="foreach: items"> <img data-bind="attr: {height: height, width: width, src: src}, click: $root.selectedItem" /> </div> <hr> <pre data-bind="text: ko.toJSON($root, null, 2)"></pre> 

Note how I use selectedItem as a click event handler. 请注意,我如何将selectedItem用作单击事件处理程序。 This is possible because in event handlers, knockout passes the relevant object (in this case, an image object from the array) as the first argument. 这是可能的,因为在事件处理程序中,剔除将相关对象(在这种情况下,是数组中的图像对象)作为第一个参数传递。 Conveniently, observables set their value to the first argument you call them with. 方便地,可观察变量将其值设置为调用它们的第一个参数。 And presto: You have click event handler that sets the last clicked object. 易如反掌:您具有单击事件处理程序,用于设置最后单击的对象。


EDIT 编辑

"I need multiple selected item then my items are just my context menu not just one selected item." “我需要多个选定的项目,然后我的项目只是我的上下文菜单,而不仅仅是一个选定的项目。”

 function loadImages() { // return $.get(url); // mockup Ajax response, in place of a real $.get call return $.Deferred().resolve({ items: [ {height: 20, width: 20, src: 'http://placehold.it/150/30ac17', title: 'image 1'}, {height: 20, width: 20, src: 'http://placehold.it/150/412ffd', title: 'image 2'}, {height: 20, width: 20, src: 'http://placehold.it/150/c672a0', title: 'image 3'} ] }).promise(); } function ImageList() { var self = this; // data self.items = ko.observableArray(); self.selectedItems = ko.observableArray(); // init loadImages().done(function (data) { ko.mapping.fromJS(data, {}, self); }); self.selectItem = function (item) { var pos = ko.utils.arrayIndexOf(self.selectedItems(), item); if (pos === -1) self.selectedItems.push(item); }; self.deselectItem = function (item) { var pos = ko.utils.arrayIndexOf(self.selectedItems(), item); if (pos !== -1) self.selectedItems.remove(item); }; } ko.applyBindings(new ImageList()) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script> <div data-bind="foreach: selectedItems"> <img data-bind="attr: {height: 25, width: 25, src: src}, click: $root.deselectItem"> </div> <div data-bind="foreach: items"> <img data-bind="attr: {height: height, width: width, src: src}, click: $root.selectItem" /> </div> <hr> <pre data-bind="text: ko.toJSON($root, null, 2)"></pre> 

Try something like this 试试这个

view: 视图:

<div data-bind="test:name,propertyName:'name'"></div>

viewModel: 视图模型:

ko.bindingHandlers.test = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        var propertyName = allBindings().propertyName; //property name here
        ko.bindingHandlers.text.update(element, valueAccessor);
        alert(propertyName)
    }
};

function Employee() {
    var self = this;
    self.name = ko.observable("John");
}

ko.applyBindings(new Employee());

working fiddle here 这里工作

This will get you the observable name. 这将为您提供可观察的名称。

This converts the valueAccessor ( function(){return name } ) to a string which is then split to remove the observable name . 这会将valueAccessorfunction(){return name } )转换为字符串,然后将其拆分以删除可观察的name

ko.bindingHandlers.GetObservableName = {
    init: function (element, valueAccessor) {
        var observableName = String(valueAccessor).split(' ')[1];
        alert(observableName);
    }
};

function Employee() {
    var self = this;
    self.name = ko.observable("John");
}

<div data-bind="GetObservableName: name"></div>

Here is a JSFiddle 这是一个JSFiddle

The index of the split method in the fiddle is different to the one in the example above. 提琴中的split方法的索引与上面的示例中的索引不同。 The above works for me in Visual Studio 2013. 以上内容适用于Visual Studio 2013。

Thanks 谢谢

<div  data-bind="foreach: {data: skills, as: 'skill'}" >
    <div data-bind="foreach: Object.keys(skill)" >
        <a data-bind="text: $data"></a> :   <a data-bind="text: skill[$data]"></a>
    </div>    
</div>


v = new function AppViewModel() {
    this.skills = [{rates:"sdfdcvxcsd", cat: 2, car:55}, {color:"sdfdcvxcsd", zoo: 2,boat:55}];
}

ko.applyBindings(v);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM