Create Country List from JSON

笑着哭i 提交于 2019-12-14 03:12:01

问题


I am trying to create a combo box with a list of countries in SAP UI5.

I have created a combo box and have created dynamic list of some countries, but to create more than 100 countries, the only easy way is to create a JSON file of countries and then populate in Controller.js.

I tried to create a JSON file but I am unsure whether I have to store it under model folder or root.

What changes do I have to make in my XML view and controller, and where should I attach countries.json file?


回答1:


You are looking at something called as "Aggregation Binding" Aggregation Binding in XML views

Here is an example to refer to which explains

  • How to create a model using data from json file
  • How to Bind model data to the XML view control(you have to bind comboBox instead of table)

How to bind json data model to an XML view

Let me know if this helps.




回答2:


Maybe you don't need to create the countries.json file at all :)

As UI5 leverages Common Locale Data Repository (CLDR) internally and provides the data via sap.ui.core.LocaleDataAPI, which includes language names, country names, currency names, singular/plural modifications, and more..

A list of supported regions for the locale data are stored in a JSON format here. In one of those files, if you look at the property "territories", you'll see that the country names are listed among them. You can filter every irrelevant territory out that is not considered a country, and then bind the rest in the items aggregation of the combo box.

Demo

sap.ui.getCore().attachInit(() => sap.ui.require([
  "sap/ui/core/Locale",
  "sap/ui/core/LocaleData",
  "sap/ui/model/json/JSONModel",
  "sap/ui/core/mvc/XMLView",
], function(Locale, LocaleData, JSONModel, XMLView) {
  "use strict";

  XMLView.create({
    definition: `<mvc:View xmlns:mvc="sap.ui.core" xmlns="sap.m"
      height="100%"
      displayBlock="true">
      <ComboBox class="sapUiTinyMargin"
        width="15rem"
        placeholder="Select a country.."
        filterSecondaryValues="true"
        showSecondaryValues="true"
        items="{
          path: '/',
          templateShareable: false,
          key: 'code',
          sorter: { path: 'name' }
        }">
        <core:ListItem xmlns:core="sap.ui.core"
          key="{code}"
          text="{name}"
          additionalText="{code}" />
      </ComboBox>
    </mvc:View>`,
    models: createCountryModel(getCountries()),
  }).then(view => view.placeAt("content"));

  function createCountryModel(countries, sizeLimit = 300) {
    const model = new JSONModel(countries);
    model.setSizeLimit(sizeLimit);
    model.setDefaultBindingMode("OneWay");
    return model;
  }

  function getCountries() {
    const territories = getTerritories();
    return extractCountriesFrom(territories, byCustomCheck());
  }

  function getTerritories(localeId) {
    const currentConfig = sap.ui.getCore().getConfiguration();
    const locale = localeId ? new Locale(localeId) : currentConfig.getLocale();
    const localeData = new LocaleData(locale);
    return localeData.getTerritories(); // includes country names
  }

  function extractCountriesFrom(territories, customCheck = () => true) {
    const isValidCountry = createCountryCheck(customCheck);
    const toObject = code => Object.freeze({
      code: code,
      name: territories[code],
    });
    const countryObjects = Object.keys(territories)
      .filter(isValidCountry)
      .map(toObject);
    return Object.freeze(countryObjects);
  }
  
  function createCountryCheck(customCheck, obviouslyNotCountries = [
    "EU", // "European Union"
    "EZ", // "Eurozone"
    "UN", // "United Nations"
    "ZZ", // "Unknown Region"
  ]) {
    return territoryCode => territoryCode.length == 2
      && !obviouslyNotCountries.includes(territoryCode)
      && customCheck(territoryCode);
  }

  function byCustomCheck() { // returns a function that returns boolean
    // E.g.: list of sanctioned countries you want to exclude
    const list = [
      "AF",
      "KP",
      "IR",
      // ...
    ];
    return countryCode => !list.includes(countryCode);
  }

}));
<script id="sap-ui-bootstrap" src="https://ui5.sap.com/resources/sap-ui-core.js"
  data-sap-ui-libs="sap.ui.core, sap.m"
  data-sap-ui-theme="sap_fiori_3"
  data-sap-ui-async="true"
  data-sap-ui-compatversion="edge"
  data-sap-ui-xx-waitfortheme="init"
></script>
<body id="content" class="sapUiBody sapUiSizeCompact"></body>

As you can see in the example, the ComboBox is successfully populated with the countries. When a new LocaleData instance is created, a request is sent immediately (currently via sync XHR) to get the data which are translated in the language that UI5 detects from the client settings. If no language could be detected, the en.json file will be retrieved.src

The above approach has the following advantages:

  • No need to create and maintain a separate "country" list. ✔️
  • Multilingual support ✔️
  • Reusability ✔️ - When UI5 tries to fetch the same locale data file, which is the case when e.g. a Calendar is used, the browser can serve the file quickly from the cache since the same file was already fetched before.

Note

When creating a JSONModel to store more than 100 country names, keep in mind to increase the size limit as well. The current default limit is 100.



来源:https://stackoverflow.com/questions/50916889/create-country-list-from-json

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!