为什么在加载 knockoutJs 时调用下拉列表的订阅事件?
Why subscribe event of dropdown is being called on load knockoutJs?
这可能是一个基本问题,但我无法得到任何解决方案。
我正在尝试在下拉列表中显示格式列表。我正在使用敲除绑定来这样做。 I want to show a specific value initially
.
当用户从下拉列表中选择其他值时,它应该显示所选值(工作正常)。
在选择任何选项时,我想获取选定的值,以便将其发送到服务器。为此,我正在使用 subscribe
。
下面是我的代码:
var obj = this;
obj.formatArray = ko.observableArray([{'text' : "MM/DD/YYYY"},
{'text' : "MM-DD-YYYY"},
{'text' : "MM.DD.YYYY"},
{'text' : "DD/MM/YYYY"},
{'text' : "DD-MM-YYYY"},
{'text' : "DD.MM.YYYY"}]);
var format1 = 'DD-MM-YYYY';
obj.formatArrayDefault = ko.observable({text :format1});
obj.formatArrayDefault.subscribe(function(newValue){
alert("default value " + format1);
alert("new value in subscribe " + newValue.text);
});
ko.applyBindings(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select class="" data-bind="options:formatArray(),optionsText:'text',value:formatArrayDefault"></select>
您可以 运行 上面的代码片段并检查,subscribe
中的 alert
正在加载并将要显示的值更改为 first value in the array
。
为什么在加载时调用 subscribe 以及为什么将值更改为第一个值?
我做错了什么?
如果问题是重复的,有人可以给 link 解决方案吗(我在这里搜索但找不到任何解决方案)。
如果您只需要任何更改后的下拉列表值。
只需要一个 observable 并将其设置为下拉列表的值,最初它将是空白的,如果下拉列表的值为空,则在您的订阅函数中添加一行比较,不要调用警报函数。
var obj = this;
obj.formatArray = ko.observableArray([{'text' : "MM/DD/YYYY"},
{'text' : "MM-DD-YYYY"},
{'text' : "MM.DD.YYYY"},
{'text' : "DD/MM/YYYY"},
{'text' : "DD-MM-YYYY"},
{'text' : "DD.MM.YYYY"}]);
var format1 = 'DD-MM-YYYY';
obj.initialLoad = true;
obj.formatArrayDefault = ko.observable(format1);
obj.formatArrayDefault.subscribe(function(newValue){
if(obj.initialLoad) {
obj.initialLoad = false;
}
else {
alert("Hello");
}
});
ko.applyBindings(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select class="projectUserAccess workflowSetOptions" data-bind="options:formatArray(),optionsText:'text',value:formatArrayDefault"></select>
===编辑===
$(document).ready(function(){
var model = {
selectedType: 2 //default Type
};
var viewModel = {
selectedType: ko.observable(model.selectedType)
, availableTypes: ko.observableArray([
{ Label: 'Type1', Code: 1 }
, { Label: 'Type2', Code: 2 }
, { Label: 'Type3', Code: 3 }
])
};
ko.applyBindings(viewModel, $("#content")[0]);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="content">
<select data-bind="value: selectedType, options: availableTypes, optionsText: 'Label', optionsValue: 'Code', optionsCaption: 'Please select...'"></select><br/>
You've selected Type: <span data-bind="text: selectedType"></span>
</div>
您的数组包含普通对象。在 javascript 中,对象比较是这样工作的:
var obj1 = { a: 1 };
var obj2 = { a: 1 };
console.log(obj1 === obj2); // false
console.log(obj1 === obj1); // true
它检查变量引用的实际对象实例,而不是它看起来的样子。许多库包含一个 "deepEquals" 函数,您可以使用它来检查两个对象是否实际上 看起来 相似,但 knockout 不使用这种机制。
因此当您设置初始选择时,它的值可能与 formatArray()[0]
处的对象相似,但敲除将无法将两者匹配在一起.即:
obj.formatArrayDefault() === obj.formatArray()[1]; // false
现在,在应用绑定时,knockout 会尝试解决选择和源数据之间的不匹配问题。它找不到与传递给 value
绑定的选择相匹配的 <option>
元素。
它必须呈现一个选定的选项,所以它默认为第一个。这是当您的初始对象被 formatArray()[0]
替换并触发订阅时。
这是一个解决方案:我们在初始值中放置对第一个对象的实际引用!
var obj = this;
obj.formatArray = ko.observableArray([{'text' : "MM/DD/YYYY"},
{'text' : "MM-DD-YYYY"},
{'text' : "MM.DD.YYYY"},
{'text' : "DD/MM/YYYY"},
{'text' : "DD-MM-YYYY"},
{'text' : "DD.MM.YYYY"}]);
var format1 = 'DD-MM-YYYY';
obj.formatArrayDefault = ko.observable(obj.formatArray()[1]);
obj.formatArrayDefault.subscribe(function(newValue){
console.log("default value " + format1);
console.log("new value in subscribe " + newValue.text);
});
ko.applyBindings(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select class="" data-bind="options:formatArray(),optionsText:'text',value:formatArrayDefault"></select>
这可能是一个基本问题,但我无法得到任何解决方案。
我正在尝试在下拉列表中显示格式列表。我正在使用敲除绑定来这样做。 I want to show a specific value initially
.
当用户从下拉列表中选择其他值时,它应该显示所选值(工作正常)。
在选择任何选项时,我想获取选定的值,以便将其发送到服务器。为此,我正在使用 subscribe
。
下面是我的代码:
var obj = this;
obj.formatArray = ko.observableArray([{'text' : "MM/DD/YYYY"},
{'text' : "MM-DD-YYYY"},
{'text' : "MM.DD.YYYY"},
{'text' : "DD/MM/YYYY"},
{'text' : "DD-MM-YYYY"},
{'text' : "DD.MM.YYYY"}]);
var format1 = 'DD-MM-YYYY';
obj.formatArrayDefault = ko.observable({text :format1});
obj.formatArrayDefault.subscribe(function(newValue){
alert("default value " + format1);
alert("new value in subscribe " + newValue.text);
});
ko.applyBindings(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select class="" data-bind="options:formatArray(),optionsText:'text',value:formatArrayDefault"></select>
您可以 运行 上面的代码片段并检查,subscribe
中的 alert
正在加载并将要显示的值更改为 first value in the array
。
为什么在加载时调用 subscribe 以及为什么将值更改为第一个值?
我做错了什么?
如果问题是重复的,有人可以给 link 解决方案吗(我在这里搜索但找不到任何解决方案)。
如果您只需要任何更改后的下拉列表值。
只需要一个 observable 并将其设置为下拉列表的值,最初它将是空白的,如果下拉列表的值为空,则在您的订阅函数中添加一行比较,不要调用警报函数。
var obj = this;
obj.formatArray = ko.observableArray([{'text' : "MM/DD/YYYY"},
{'text' : "MM-DD-YYYY"},
{'text' : "MM.DD.YYYY"},
{'text' : "DD/MM/YYYY"},
{'text' : "DD-MM-YYYY"},
{'text' : "DD.MM.YYYY"}]);
var format1 = 'DD-MM-YYYY';
obj.initialLoad = true;
obj.formatArrayDefault = ko.observable(format1);
obj.formatArrayDefault.subscribe(function(newValue){
if(obj.initialLoad) {
obj.initialLoad = false;
}
else {
alert("Hello");
}
});
ko.applyBindings(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select class="projectUserAccess workflowSetOptions" data-bind="options:formatArray(),optionsText:'text',value:formatArrayDefault"></select>
===编辑===
$(document).ready(function(){
var model = {
selectedType: 2 //default Type
};
var viewModel = {
selectedType: ko.observable(model.selectedType)
, availableTypes: ko.observableArray([
{ Label: 'Type1', Code: 1 }
, { Label: 'Type2', Code: 2 }
, { Label: 'Type3', Code: 3 }
])
};
ko.applyBindings(viewModel, $("#content")[0]);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="content">
<select data-bind="value: selectedType, options: availableTypes, optionsText: 'Label', optionsValue: 'Code', optionsCaption: 'Please select...'"></select><br/>
You've selected Type: <span data-bind="text: selectedType"></span>
</div>
您的数组包含普通对象。在 javascript 中,对象比较是这样工作的:
var obj1 = { a: 1 };
var obj2 = { a: 1 };
console.log(obj1 === obj2); // false
console.log(obj1 === obj1); // true
它检查变量引用的实际对象实例,而不是它看起来的样子。许多库包含一个 "deepEquals" 函数,您可以使用它来检查两个对象是否实际上 看起来 相似,但 knockout 不使用这种机制。
因此当您设置初始选择时,它的值可能与 formatArray()[0]
处的对象相似,但敲除将无法将两者匹配在一起.即:
obj.formatArrayDefault() === obj.formatArray()[1]; // false
现在,在应用绑定时,knockout 会尝试解决选择和源数据之间的不匹配问题。它找不到与传递给 value
绑定的选择相匹配的 <option>
元素。
它必须呈现一个选定的选项,所以它默认为第一个。这是当您的初始对象被 formatArray()[0]
替换并触发订阅时。
这是一个解决方案:我们在初始值中放置对第一个对象的实际引用!
var obj = this;
obj.formatArray = ko.observableArray([{'text' : "MM/DD/YYYY"},
{'text' : "MM-DD-YYYY"},
{'text' : "MM.DD.YYYY"},
{'text' : "DD/MM/YYYY"},
{'text' : "DD-MM-YYYY"},
{'text' : "DD.MM.YYYY"}]);
var format1 = 'DD-MM-YYYY';
obj.formatArrayDefault = ko.observable(obj.formatArray()[1]);
obj.formatArrayDefault.subscribe(function(newValue){
console.log("default value " + format1);
console.log("new value in subscribe " + newValue.text);
});
ko.applyBindings(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select class="" data-bind="options:formatArray(),optionsText:'text',value:formatArrayDefault"></select>