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

时间:2015-08-05 03:13:33

标签: javascript knockout.js

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>

有没有办法获得可观察的名字?不是可观察的价值。

TIA。

更新

这是代码段。

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'" />

当您点击包含selectItem的图片时,第一张图片应替换为src属性。如果您有更好的方法,请建议。

仅供参考,items可观测量内的属性是图像的链接。

TIA。

4 个答案:

答案 0 :(得分:1)

您可以通过自定义绑定获得自己的优势。

底线是:您不需要自定义绑定来执行您想要的操作。这很容易 - 如果你不复杂的话:

&#13;
&#13;
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())
&#13;
<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>
&#13;
&#13;
&#13;

请注意我如何使用selectedItem作为点击事件处理程序。这是可能的,因为在事件处理程序中,knockout将相关对象(在本例中是数组中的图像对象)作为第一个参数传递。方便的是,observables将它们的值设置为您调用它们的第一个参数。并且presto:你有点击事件处理程序来设置最后点击的对象。

修改

  

&#34;我需要多个选定的项目,然后我的项目只是我的上下文菜单而不仅仅是一个选定的项目。&#34;

&#13;
&#13;
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())
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

尝试这样的事情

查看:

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

<强>视图模型:

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());

工作小提琴 here

答案 2 :(得分:0)

这将为您提供可观察的名称。

这会将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>

这是JSFiddle

小提琴中split方法的索引与上例中的索引不同。以上内容适用于Visual Studio 2013。

由于

答案 3 :(得分:0)

<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);