在Javascript中,有没有办法评估一个可能是也可能不是函数的变量

时间:2013-10-24 13:34:03

标签: javascript knockout.js knockout-mapping-plugin

我有一个复杂的javascript变量,里面有许多嵌套变量,每个变量都可以包含自己的嵌套变量......当我执行我的淘汰映射时,有时嵌套变量被设置为对象,而其他时候则设置为完全相同的变量是功能。所以当我对这些嵌套变量的数据绑定期望下一次该变量现在是一个函数时,绑定不会更新。

下面的小提琴让我知道我所看到的:

http://jsfiddle.net/Eves/AUcGM/2/

HTML:

<p> <span>Name:</span>
 <span data-bind="text: TempData().objectA.Name"></span>

    <button id="update" data-bind="click: Update">Update!</button>
</p>

使用Javascript:

var ViewModel = function (data) {
    var me = this;
    me.TempData = ko.observable(data);

    me.Update = function () {


        ko.mapping.fromJS(temp2, {}, me);
    };

    return me;
};

var temp1 = {
    objectA: {
        Name: 'temp1.objectA.Name'
    }
};
var temp2 = {
    objectA: function () {
        this.Name = 'temp2.objectA.Name';
        return this;
    }
};
window.viewModel = ko.mapping.fromJS(new ViewModel(temp1));
ko.applyBindings(window.viewModel);

最初,span文本显示“temp1.objectA.Name”。但是,如果单击更新按钮并且绑定从temp1对象切换到temp2对象,因为“objectA”现在是一个函数,数据绑定永远不会更新。如果我要将span的数据绑定更改为“TempData()。objectA()。Name”那么temp2将正常工作......但是那会破坏temp1。

所以问题是:

有没有办法总是将变量评估为对象或函数?

我怀疑无论函数或对象如何,我都可以使用ko.computed来获取适当的值。但考虑到我真正处理的对象的复杂性,这将变得非常混乱。

1 个答案:

答案 0 :(得分:1)

我没有阅读你的整个问题,但有一个快速的答案 -

var returnedValue = ko.unwrap(possibleFunction);

(在旧版本的ko中,这是ko.utils.unwrapObservable)

使用它的一个好方法是使用自定义绑定处理程序来解包值,无论它是否是函数。

ko.bindingHandlers.returnAction = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = ko.unwrap(valueAccessor());
        // now value is a value no matter what the element's value was set as

        $(element).keydown(function (e) {
            if (e.which === 13) {
                value(viewModel);
            }
        });
    }
};

修改

这是传递各种对象的工作小提琴示例 - http://jsfiddle.net/5udhU/3/

它演示了传递一个字符串,一个observable,一个计算器和一个所有正确评估的函数。