我正在使用Knockout.js开发一个网站,但我的问题更为笼统,所以不要专注于此。
我通过变量名引用自身内的对象,在本例中为viewModel
,如下所示:
var viewModel = {
propA: "propA",
fnA: function () {
alert("I am " + viewModel.propA); //the same as this.propA
}
};
这样,在涉及子对象和其他“花哨”的东西时,我不会遇到任何麻烦。
现在,我需要将另一个对象合并到我的viewModel中,但是我遇到了一个引用问题:
g_test = {}; //The way with this global variable is just for demonstration purposes
(function () {
var viewModel = {
propA: "propA",
fnA: function () {
alert("I am " + viewModel.propB);
}
};
g_test.vmA = viewModel;
})();
(function () {
var viewModel = {
propB: "propB",
fnB: function () {
alert("I am " + viewModel.propA);
}
}
/** merge viewModel "A" into viewModel "B" */
var vmA = g_test.vmA;
for (var key in vmA) {
if (vmA.hasOwnProperty(key)) {
viewModel[key] = vmA[key];
}
}
viewModel.fnA(); //I am undefined
viewModel.fnB(); //I am propA
})();
如您所见,fnB
知道propA
,但fnA
不知道propB
。
然后使用this
作为对viewModel
对象的引用。但是我不希望遍历我的整个对象并用viewModel
替换每个this
或者在需要时引入相应的“辅助变量”,因为这需要我很长时间。另外,对我来说,这意味着合并两个没有彼此双向知识的物体是不可能的。
是否有一种让viewModel
中的fnA
变量指向viewModel“B”而不必知道viewModel“B”的有意义方法?
答案 0 :(得分:0)
创建多个viewModel然后尝试合并它们似乎是一个有问题的方法,我不知道你想用它实现什么。可能有更好的方法(至少,使用this
是创建mixins)的正确选择。但是假设现在有一个很好的理由或者现在重做它的努力太多了,让我们来看看你的问题。
您有两个viewModel,并且您希望以这样的方式合并它们,即每个都知道另一个的成员。你在一个方向合并它们,所以B知道A,但A不知道B.你需要合并另一个方向。 Object.assign
是执行循环操作的便捷方式,但如果您使用的是Object.assign
之前的浏览器,则可以添加另一个遍历viewModel
的循环并将其中的属性复制到vmA
。
结果是你有两个viewModel,它们的方法相互引用。每个都有propA
,propB
,fnA
和fnB
,但fnA
(在两个对象中)都指对象A
的成员和反之亦然。
g_test = {}; //The way with this global variable is just for demonstration purposes
function mergeObjects(obj1, obj2) {
Object.assign(obj1, obj2);
Object.assign(obj2, obj1);
}
(function() {
var viewModel = {
propA: "propA",
fnA: function() {
alert("fnA: I am " + viewModel.propB);
}
};
g_test.vmA = viewModel;
})();
(function() {
var viewModel = {
propB: "propB",
fnB: function() {
alert("fnB: I am " + viewModel.propA);
}
}
mergeObjects(g_test.vmA, viewModel);
// to demonstrate which value is outputted by which function
g_test.vmA.propA = "A.propA"; // not used
g_test.vmA.propB = "A.propB"; // used by fnA
viewModel.propA = "B.propA"; // used by fnB
viewModel.propB = "B.propB"; // not used
viewModel.fnA(); //I am A.propB
viewModel.fnB(); //I am B.propA
// also
g_test.vmA.fnA();
g_test.vmA.fnB();
})();