Как иметь значение id(первичного ключа) в выбранном обновлении соответствующих связанных значений

Короче говоря, я хочу, чтобы поле выбора заполнялось доменом со значениями параметров, являющимися идентификатором / первичным ключом, а когда выбор был изменен, я бы хотел, чтобы обновлялись связанные значения соответствующих записей. Вы можете видеть, что bureau_id() здесь меняет, но не имя или personal_area той же записи. Я чувствую, что здесь есть наблюдаемое, но я использовал map(), и я не могу понять, как подключиться к нему. В модели представления я также думал, что параметр 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 ответ

Есть несколько проблем с вашей текущей версией. Во-первых, вы клонируете элементы данных из 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>

Другие вопросы по тегам