如何让 select 中的 id(primary key) 值更新对应的绑定值
How to have id(primary key) value in a select update corresponding bound values
简而言之,我想要一个 select 框,其中填充了一个域,选项值为 id/primary 键,当 select 更改时,我想要相应记录的绑定值已更新。您可以看到 bureau_id() 这里确实发生了变化,但同一条记录的名称或 personal_area 没有变化。我觉得这里有一个 observable,但我使用了 map() 并且我不知道如何利用它。在视图模型中,我还认为 id 参数可能会以某种方式帮助解决这个问题。
我也想知道是否有更好的方法使用域通过 id 和更新与该 id 相关的域字段来控制数据中项目的编辑。想法是在单击值时显示 select,并在 selection 生成后显示 return 到文本。
$(function() {
$.views.viewModels({
Root: {
getters: [
{
getter: "bureaus",
type: "Bureau"
}
]
},
Bureau: {
id: "bureau_id",
getters: ["bureau_id","name","personal_area"]
}
});
data = {
bureaus: [
{
"bureau_id":40,
"name":"Bureau of Emergency Communications",
"personal_area":1200
},
{
"bureau_id":30,
"name":"Office of the City Attorney",
"personal_area":1090
}
]
}
domains = {
"bureau": [
{
"bureau_id":41,
"name":"Bureau of Development Services",
"personal_area":1210
},
{
"bureau_id":40,
"name":"Bureau of Emergency Communications",
"personal_area":1200
},
{
"bureau_id":39,
"name":"Bureau of Emergency Management",
"personal_area":1190
},
{
"bureau_id":22,
"name":"Bureau of Environmental Services",
"personal_area":1010
},
{
"bureau_id":42,
"name":"Bureau of Fire and Police Disability and Retirement Fund",
"personal_area":1230
},
{
"bureau_id":43,
"name":"Bureau of Human Resources",
"personal_area":1240
},
{
"bureau_id":45,
"name":"Bureau of Internal Business Services",
"personal_area":1260
},
{
"bureau_id":36,
"name":"Bureau of Parks and Recreation",
"personal_area":1160
},
{
"bureau_id":34,
"name":"Bureau of Planning and Sustainability",
"personal_area":1140
},
{
"bureau_id":46,
"name":"Bureau of Revenue & Financial Services",
"personal_area":1275
},
{
"bureau_id":44,
"name":"Bureau of Technology Services",
"personal_area":1250
},
{
"bureau_id":49,
"name":"City Budget Office",
"personal_area":1320
},
{
"bureau_id":31,
"name":"Office of City Auditor Mary Hull Caballero",
"personal_area":1100
},
{
"bureau_id":26,
"name":"Office of Commissioner Amanda Fritz",
"personal_area":1050
},
{
"bureau_id":29,
"name":"Office of Commissioner Chloe Eudaly",
"personal_area":1080
},
{
"bureau_id":28,
"name":"Office of Commissioner Dan Saltzman",
"personal_area":1070
},
{
"bureau_id":27,
"name":"Office of Commissioner Nick Fish",
"personal_area":1060
},
{
"bureau_id":37,
"name":"Office of Community & Civic Life",
"personal_area":1170
},
{
"bureau_id":48,
"name":"Office of Equity and Human Rights",
"personal_area":1310
},
{
"bureau_id":24,
"name":"Office of Government Relations",
"personal_area":1030
},
{
"bureau_id":47,
"name":"Office of Management and Finance",
"personal_area":1290
},
{
"bureau_id":38,
"name":"Office of Mayor Ted Wheeler",
"personal_area":1180
},
{
"bureau_id":30,
"name":"Office of the City Attorney",
"personal_area":1090
},
{
"bureau_id":35,
"name":"Police Bureau",
"personal_area":1150
},
{
"bureau_id":32,
"name":"Portland Bureau of Transportation",
"personal_area":1120
},
{
"bureau_id":23,
"name":"Portland Fire & Rescue",
"personal_area":1020
},
{
"bureau_id":25,
"name":"Portland Housing Bureau",
"personal_area":1040
},
{
"bureau_id":33,
"name":"Portland Water Bureau",
"personal_area":1130
}
]
};
let vm = $.views.viewModels.Root.map(data);
$.templates('#root-tmpl').link('#content', vm, domains);
});
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://www.jsviews.com/download/jsviews.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet">
<script src="https://www.jsviews.com/download/sample-tag-controls/jsviews-jqueryui-widgets.min.js"></script>
<script id="root-tmpl" type="text/x-jsrender">
<ul>
{^{for bureaus() tmpl="#bureau-tmpl"}}
{{/for}}
</ul>
</script>
<script id="bureau-tmpl" type="text/x-jsrender">
<li>
{^{>name()}} ({^{>personal_area()}}) {^{>bureau_id()}}
{^{selectmenu bureau_id() name="bureau_id" class="bureau-select"}}
{^{for ~bureau}}
<option data-link="value{:bureau_id}">{^{>name}} ({^{>personal_area}})</option>
{{/for}}
{{/selectmenu}}
</li>
</script>
</head>
<body>
<div id="content"></div>
</body>
</html>
您当前的版本存在一些问题。一是您正在将数据项从 domains.bureau[n] 克隆到 data.bureaus[n]。如果您选择不同的下拉项,那么您将需要以某种方式将所选项目克隆到 data.bureau。在值可能发生变化(即编辑、服务器数据等)的真实情况下,您似乎也很容易遇到一些数据完整性问题
无论如何,这是一个建议的替代设计。 data.bureaus 重命名为 data.selected,并且只有 selected_id 是对相应 bureau_id 的查找。
域和当前 data.selected 都映射到 ViewModel 实例。注意这一行:
getSelectedBureau.depends = "selected_id";
确保当 selected_id 更改时,以下内容也会更新:
{^{>selectedBureau()^name()}} ({^{>selectedBureau()^personal_area()}}) ...
$(function() {
$.views.viewModels({
Root: {
getters: [
{getter: "selected", type: "SelectedBureau"},
{getter: "bureaus", type: "Bureau"}
]
},
SelectedBureau: {
getters: ["selected_id"],
extend: {
selectedBureau: getSelectedBureau,
bureaus: function() {
return vm.bureaus();
}
}
},
Bureau: {
id: "bureau_id",
getters: ["bureau_id","name","personal_area"]
}
});
function getSelectedBureau() { // lookup to find the corresonding bureau VM
let bureaus = vm.bureaus(),
l = bureaus.length;
while (l--) {
if (this.selected_id() === "" + bureaus[l].bureau_id()) {
return bureaus[l];
}
}
}
getSelectedBureau.depends = "selected_id"; // So selectedBureau() updates when selected_id changes
let data = {
selected: [
{
"selected_id":"40"
},
{
"selected_id":"30"
}
],
"bureaus": [
{
"bureau_id":41,
"name":"Bureau of Development Services",
"personal_area":1210
},
{
"bureau_id":40,
"name":"Bureau of Emergency Communications",
"personal_area":1200
},
{
"bureau_id":49,
"name":"City Budget Office",
"personal_area":1320
},
{
"bureau_id":31,
"name":"Office of City Auditor Mary Hull Caballero",
"personal_area":1100
},
{
"bureau_id":30,
"name":"Office of the City Attorney",
"personal_area":1090
}
]
};
let vm = $.views.viewModels.Root.map(data);
$.templates('#root-tmpl').link('#content', vm);
});
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://www.jsviews.com/download/jsviews.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet">
<script src="https://www.jsviews.com/download/sample-tag-controls/jsviews-jqueryui-widgets.min.js"></script>
<script id="root-tmpl" type="text/x-jsrender">
<ul>
{^{for selected() tmpl="#bureau-tmpl"/}}
</ul>
</script>
<script id="bureau-tmpl" type="text/x-jsrender">
<li>
{^{>selectedBureau()^name()}} ({^{>selectedBureau()^personal_area()}}) {^{>selected_id()}}
{^{selectmenu selected_id() name="bureau_id" class="bureau-select"}}
{^{for bureaus()}}
<option value="{{:bureau_id()}}">{{>name()}} ({{>personal_area()}})</option>
{{/for}}
{{/selectmenu}}
</li>
</script>
</head>
<body>
<div id="content"></div>
</body>
</html>
简而言之,我想要一个 select 框,其中填充了一个域,选项值为 id/primary 键,当 select 更改时,我想要相应记录的绑定值已更新。您可以看到 bureau_id() 这里确实发生了变化,但同一条记录的名称或 personal_area 没有变化。我觉得这里有一个 observable,但我使用了 map() 并且我不知道如何利用它。在视图模型中,我还认为 id 参数可能会以某种方式帮助解决这个问题。
我也想知道是否有更好的方法使用域通过 id 和更新与该 id 相关的域字段来控制数据中项目的编辑。想法是在单击值时显示 select,并在 selection 生成后显示 return 到文本。
$(function() {
$.views.viewModels({
Root: {
getters: [
{
getter: "bureaus",
type: "Bureau"
}
]
},
Bureau: {
id: "bureau_id",
getters: ["bureau_id","name","personal_area"]
}
});
data = {
bureaus: [
{
"bureau_id":40,
"name":"Bureau of Emergency Communications",
"personal_area":1200
},
{
"bureau_id":30,
"name":"Office of the City Attorney",
"personal_area":1090
}
]
}
domains = {
"bureau": [
{
"bureau_id":41,
"name":"Bureau of Development Services",
"personal_area":1210
},
{
"bureau_id":40,
"name":"Bureau of Emergency Communications",
"personal_area":1200
},
{
"bureau_id":39,
"name":"Bureau of Emergency Management",
"personal_area":1190
},
{
"bureau_id":22,
"name":"Bureau of Environmental Services",
"personal_area":1010
},
{
"bureau_id":42,
"name":"Bureau of Fire and Police Disability and Retirement Fund",
"personal_area":1230
},
{
"bureau_id":43,
"name":"Bureau of Human Resources",
"personal_area":1240
},
{
"bureau_id":45,
"name":"Bureau of Internal Business Services",
"personal_area":1260
},
{
"bureau_id":36,
"name":"Bureau of Parks and Recreation",
"personal_area":1160
},
{
"bureau_id":34,
"name":"Bureau of Planning and Sustainability",
"personal_area":1140
},
{
"bureau_id":46,
"name":"Bureau of Revenue & Financial Services",
"personal_area":1275
},
{
"bureau_id":44,
"name":"Bureau of Technology Services",
"personal_area":1250
},
{
"bureau_id":49,
"name":"City Budget Office",
"personal_area":1320
},
{
"bureau_id":31,
"name":"Office of City Auditor Mary Hull Caballero",
"personal_area":1100
},
{
"bureau_id":26,
"name":"Office of Commissioner Amanda Fritz",
"personal_area":1050
},
{
"bureau_id":29,
"name":"Office of Commissioner Chloe Eudaly",
"personal_area":1080
},
{
"bureau_id":28,
"name":"Office of Commissioner Dan Saltzman",
"personal_area":1070
},
{
"bureau_id":27,
"name":"Office of Commissioner Nick Fish",
"personal_area":1060
},
{
"bureau_id":37,
"name":"Office of Community & Civic Life",
"personal_area":1170
},
{
"bureau_id":48,
"name":"Office of Equity and Human Rights",
"personal_area":1310
},
{
"bureau_id":24,
"name":"Office of Government Relations",
"personal_area":1030
},
{
"bureau_id":47,
"name":"Office of Management and Finance",
"personal_area":1290
},
{
"bureau_id":38,
"name":"Office of Mayor Ted Wheeler",
"personal_area":1180
},
{
"bureau_id":30,
"name":"Office of the City Attorney",
"personal_area":1090
},
{
"bureau_id":35,
"name":"Police Bureau",
"personal_area":1150
},
{
"bureau_id":32,
"name":"Portland Bureau of Transportation",
"personal_area":1120
},
{
"bureau_id":23,
"name":"Portland Fire & Rescue",
"personal_area":1020
},
{
"bureau_id":25,
"name":"Portland Housing Bureau",
"personal_area":1040
},
{
"bureau_id":33,
"name":"Portland Water Bureau",
"personal_area":1130
}
]
};
let vm = $.views.viewModels.Root.map(data);
$.templates('#root-tmpl').link('#content', vm, domains);
});
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://www.jsviews.com/download/jsviews.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet">
<script src="https://www.jsviews.com/download/sample-tag-controls/jsviews-jqueryui-widgets.min.js"></script>
<script id="root-tmpl" type="text/x-jsrender">
<ul>
{^{for bureaus() tmpl="#bureau-tmpl"}}
{{/for}}
</ul>
</script>
<script id="bureau-tmpl" type="text/x-jsrender">
<li>
{^{>name()}} ({^{>personal_area()}}) {^{>bureau_id()}}
{^{selectmenu bureau_id() name="bureau_id" class="bureau-select"}}
{^{for ~bureau}}
<option data-link="value{:bureau_id}">{^{>name}} ({^{>personal_area}})</option>
{{/for}}
{{/selectmenu}}
</li>
</script>
</head>
<body>
<div id="content"></div>
</body>
</html>
您当前的版本存在一些问题。一是您正在将数据项从 domains.bureau[n] 克隆到 data.bureaus[n]。如果您选择不同的下拉项,那么您将需要以某种方式将所选项目克隆到 data.bureau。在值可能发生变化(即编辑、服务器数据等)的真实情况下,您似乎也很容易遇到一些数据完整性问题
无论如何,这是一个建议的替代设计。 data.bureaus 重命名为 data.selected,并且只有 selected_id 是对相应 bureau_id 的查找。
域和当前 data.selected 都映射到 ViewModel 实例。注意这一行:
getSelectedBureau.depends = "selected_id";
确保当 selected_id 更改时,以下内容也会更新:
{^{>selectedBureau()^name()}} ({^{>selectedBureau()^personal_area()}}) ...
$(function() {
$.views.viewModels({
Root: {
getters: [
{getter: "selected", type: "SelectedBureau"},
{getter: "bureaus", type: "Bureau"}
]
},
SelectedBureau: {
getters: ["selected_id"],
extend: {
selectedBureau: getSelectedBureau,
bureaus: function() {
return vm.bureaus();
}
}
},
Bureau: {
id: "bureau_id",
getters: ["bureau_id","name","personal_area"]
}
});
function getSelectedBureau() { // lookup to find the corresonding bureau VM
let bureaus = vm.bureaus(),
l = bureaus.length;
while (l--) {
if (this.selected_id() === "" + bureaus[l].bureau_id()) {
return bureaus[l];
}
}
}
getSelectedBureau.depends = "selected_id"; // So selectedBureau() updates when selected_id changes
let data = {
selected: [
{
"selected_id":"40"
},
{
"selected_id":"30"
}
],
"bureaus": [
{
"bureau_id":41,
"name":"Bureau of Development Services",
"personal_area":1210
},
{
"bureau_id":40,
"name":"Bureau of Emergency Communications",
"personal_area":1200
},
{
"bureau_id":49,
"name":"City Budget Office",
"personal_area":1320
},
{
"bureau_id":31,
"name":"Office of City Auditor Mary Hull Caballero",
"personal_area":1100
},
{
"bureau_id":30,
"name":"Office of the City Attorney",
"personal_area":1090
}
]
};
let vm = $.views.viewModels.Root.map(data);
$.templates('#root-tmpl').link('#content', vm);
});
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://www.jsviews.com/download/jsviews.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet">
<script src="https://www.jsviews.com/download/sample-tag-controls/jsviews-jqueryui-widgets.min.js"></script>
<script id="root-tmpl" type="text/x-jsrender">
<ul>
{^{for selected() tmpl="#bureau-tmpl"/}}
</ul>
</script>
<script id="bureau-tmpl" type="text/x-jsrender">
<li>
{^{>selectedBureau()^name()}} ({^{>selectedBureau()^personal_area()}}) {^{>selected_id()}}
{^{selectmenu selected_id() name="bureau_id" class="bureau-select"}}
{^{for bureaus()}}
<option value="{{:bureau_id()}}">{{>name()}} ({{>personal_area()}})</option>
{{/for}}
{{/selectmenu}}
</li>
</script>
</head>
<body>
<div id="content"></div>
</body>
</html>