如何在选择中具有id(主键)值更新相应的绑定值

时间:2019-02-26 18:34:40

标签: jsrender jsviews

简而言之,我想要一个选择框,其中填充了一个域,其选项值为id /主键,当选择更改时,我希望更新相应记录的绑定值。您可以看到此处的Bureau_id()确实发生了变化,但同一记录的名称或personal_area却没有变化。我觉得这里有一个可观察到的地方,但是我使用了map(),但我不知道该如何使用它。在视图模型中,我还认为id参数可能对此有所帮助。

我还想知道是否有更好的方法使用域来通过id控制数据中项目的编辑并更新与该id相关的域字段。当时的想法是在单击值时显示一个选择,并在选择后返回到文本。

$(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>

1 个答案:

答案 0 :(得分:0)

当前版本存在很多问题。一种是将数据项从domains.bureau [n]克隆到data.bureaus [n]。如果选择其他下拉菜单项,则需要选择的菜单项以某种方式克隆到data.bureau。在值可能发生变化的真实情况下(例如,通过编辑,服务器数据等),您似乎也很容易遇到一些数据完整性问题

无论如何,这是建议的替代设计。 data.bureaus重命名为data.selected,并且仅具有selected_id,它是对相应的Bureau_id的查找。

所选的域和当前数据都映射到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>