【问题标题】:Unable to process binding, country is not defined无法处理绑定,国家未定义
【发布时间】:2016-05-15 05:46:42
【问题描述】:

我正在尝试将 <select> 绑定到 ko.observableArray 并且收到此错误:

Uncaught ReferenceError: Unable to process binding "options: function (){return _countries }" 消息:国家未定义

这是我的代码。

HTML:

<!-- This is the home page -->

<html>

<head>
    <title>The Vegan Repository</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- Load libraries -->



    <!-- System.js -->
    <script 
        src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.18.4/system-csp-production.js">
    </script>

    <!-- JQuery -->
    <script 
        src="bower_components/jquery/dist/jquery.min.js">
    </script>

    <!-- Bootstrap CSS -->
    <link 
        rel="stylesheet" 
        href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" 
        integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7"
        crossorigin="anonymous">

    <!-- Bootstrap JS -->
    <script 
        src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" 
        integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
        crossorigin="anonymous">
    </script>

    <!-- Knockout JS -->
    <script 
        src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js">
    </script>

    <!-- Styles -->
    <link rel="stylesheet" type="text/css" href="styles/image.css">
    <link rel="stylesheet" type="text/css" href="styles/text.css">
    <link rel="stylesheet" type="text/css" href="styles/header.css">
    <link rel="stylesheet" type="text/css" href="styles/form.css">
    <link rel="stylesheet" type="text/css" href="styles/select.css">

    <!-- Google Maps API -->
    <!-- <script src="http://maps.googleapis.com/maps/api/js"></script>
    <script src="scripts/map.js"></script> -->
    <script src="scripts/scroll_to_anchor.js"></script>
    <script src="scripts/xml2json.min.js"></script>
    <script src="scripts/country.js"></script>

</head>
<body >
    <div style="margin-bottom: 100px;" class="full_size dimmed">
        <div style="position:fixed; z-index: -1;">
        <video 
            style="position:fixed;" 
            autoplay loop muted
            poster="assets/images/home_page/polina.jpg" 
            id="bgvid">
            <!--<source src="polina.webm" type="video/webm">-->
            <source src="assets/videos/polina.mp4" type="video/mp4">
        </video>
        </div>

        <div class="header dim">
            <a href="http://www.w3schools.com" ><h5 id="app-name" class="nav-item clickable white-text medium-text left-text">THE VEGAN REPOSITORY</h5></a>
            <a href="http://www.w3schools.com" ><h5 (click)="clicked()" id="sign-in-button" class="nav-item clickable brand-colour-text medium-text right-text with-border">SIGN UP FREE</h5></a>
            <a href="http://www.w3schools.com" ><h5 class="nav-item clickable white-text medium-text right-text">LOGIN</h5></a>
            <a href="#home_page_footer" ><h5 class="nav-item clickable white-text medium-text right-text" >BLOG</h5></a>
            <a href="#home_page_footer" ><h5 class="nav-item clickable white-text medium-text right-text" >ABOUT</h5></a>

        </div>

        <div id="motto-text" class="vertical-center">
            <h5 class="white-text medium-text">THE VEGAN REPOSITORY</h5>
            <h1 id="main-text" class=" text-center white-text light-text extra-large-text">FIND VEGAN PRODUCTS NEAR YOU</h1>
            <a id="try-now-button" class="with-border clickable" href="#find-vegan-products-page" ><h5  class=" text-center medium-text">TRY NOW</h5></a>
        </div>
    </div>
    <!--[if lt IE 9]>
    <script>
        document.createElement('video');
    </script>
    <![endif]-->

    <?php
        $host = 'localhost';
        $port = 8889;
        $servername = "$host:$port";
        $username = "root";
        $password = "root";
        $db = "myDB";

        // Create connection
        $conn = new mysqli($servername, $username, $password, $db);
        // Check connection
        if ($conn->connect_error) {
            die("Connection failed: " . $conn->connect_error);
        } 

        // Create database
        /*$sql = "CREATE DATABASE myDB";*/

        // Create table
        /*$sql = "CREATE TABLE Persons
                (   PersonID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
                    LastName varchar(255),
                    FirstName varchar(255),
                    Address varchar(255),
                    City varchar(255)
                );";*/

        // Insert row into table
        $sql = "INSERT INTO Persons (Firstname, Lastname, Address, City)
                VALUES  ('John', 'Doe', '44 Vulcan Lane', 'Auckland'),
                        ('Jane', 'Doe', '44 Vulcan Lane', 'Auckland'),
                        ('Becky', 'Smith', '5 Freemans Lane', 'Kaitaia'),
                        ('Chris', 'Johnson', '18 Snow Drive', 'Christchurch');
                ";

        // Delete all rows
        /*$sql = "DELETE FROM Persons";*/


        /*if ($conn->query($sql) === TRUE) {
            echo "Database created successfully";
        } else {
            echo "Error creating database: " . $conn->error;
        }*/

        $conn->close();
    ?>

    <!-- <div id="googleMap" style="height:500px;"></div> -->

    <div id="find-vegan-products-page" style="height:900px;">
        <div class="form-background">
        <div class="container-fluid" style="padding: 40px;">
            <h1>Filter Your Search!</h1>
            <form role="form">
            <div class="row">
                <div class="form-group col-sm-6">
                   <!-- <select id="country-select" class="form-control input-control"></select>-->
                    <div class="select">
                        <span class="arr"></span>
                        <select data-bind=" options: _countries,
                                            optionsText: country.countryName,
                                            value: country.geonameId,
                                            optionsCaption: 'Choose...'">
                        </select>
                    </div>
                </div>
                <div class="form-group col-sm-6">
                    <div class="select">
                        <span class="arr"></span>
                        <select id="city-select">
                        </select>
                    </div>
                </div>
            </div>


            </form>
         </div>


</div>

        </div>
    </div>
</body>
</html>

打字稿:

class HomeViewModel {
    _countries = ko.observableArray();
    _cities = ko.observableArray();

    constructor(allCountries) {
        for (var index = 0; index < allCountries.length; index++) {
            this._countries.push(allCountries[index]);
        }
    }
}

var _homeViewModel: HomeViewModel;

$(document).ready(function() {
    $("#city-select").append('<option selected>Any Region</option>');
    $.ajax({
        url: "http://api.geonames.org/countryInfo?username=elion"
    }).then(function(allCountriesXML) {
        var allCountriesJSON = xml2json(allCountriesXML);
        var allCountries = JSON.parse(allCountriesJSON);
        _homeViewModel = new HomeViewModel(allCountries.geonames);
        ko.applyBindings(_homeViewModel);
    }
);

这是 allCountries 的值(从控制台复制粘贴的小样本):

[0 … 99]
0: Object
country: Object
areaInSqKm: "468.0"
capital: "Andorra la Vella"
continent: "EU"
continentName: "Europe"
countryCode: "AD"
countryName: "Andorra"
currencyCode: "EUR"
east: "1.786..."

如果我将 html 更改为:

<select data-bind=" options: _countries">
                        </select>

它可以工作,但&lt;select&gt; 在选择框中显示 [object][object]。

如果我将 viewModel 的构造函数更改为:

constructor(allCountries) {
        for (var index = 0; index < allCountries.length; index++) {
            this._countries.push(allCountries[index].country.countryName);
        }
    }

同时保持 html 如下:

<select data-bind=" options: _countries">
                        </select>

它可以工作,但我在 &lt;select&gt; 中没有任何价值,因为我已经摆脱了 javascript 对象数组并将其变成了字符串数组。

如何将 javascript 对象数组绑定到 &lt;select&gt; 而不会抱怨 _countries 未定义?这是因为我在文档准备好后推入 _countries 数组,并且在 html 中我在加载文档之前绑定了 ko.observableArray 吗?如果是这样,我确实尝试使用一个值初始化 ko.observableArray,但它没有解决问题。

【问题讨论】:

  • 您是否尝试将 optionsText: 'countryName', optionsValue: 'someIdOfCountry' 添加到绑定中? ..jsfiddle.net/8mx087a0/8
  • 如果您发布代码,如果您将其缩减到仅相关部分会有所帮助。

标签: javascript knockout.js typescript


【解决方案1】:

使用 Rohith 的答案。只是为了进一步详细说明,导致错误的不是_countries,而是这些optionsText: country.countryName, value: country.geonameId,您的视图模型不知道任何国家,这些值位于_countries observable 数组中。并且您错误地使用了options 数据绑定参数。

查看docs 了解有关此绑定的更多详细信息。

只是为了满足您在这里需要的内容,首先您使用了optionsText,那个值应该是'countryName'。然后对于value,这将是保存所选选项的可观察对象。因此,在您的视图模型中,您需要添加类似 countryselectedCountry 或任何您喜欢的名称。

把它写成代码,你的改变应该是这样的。 更改视图模型:

class HomeViewModel {
    _countries = ko.observableArray();
    _cities = ko.observableArray();
    selectedCountry = ko.observable();

    constructor(allCountries) {
        for (var index = 0; index < allCountries.length; index++) {
            this._countries.push(allCountries[index]);
        }
    }
}

然后在你的 html 数据绑定中它会是这样的。

<div class="select">
    <span class="arr"></span>
    <select data-bind="options: _countries,
                       optionsText: 'countryName',
                       value: selectedCountry,
                       optionsCaption: 'Choose...'">
    </select>
</div>

【讨论】:

    猜你喜欢
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 2022-01-11
    • 2015-01-22
    • 1970-01-01
    • 2017-07-18
    • 1970-01-01
    • 2016-03-31
    相关资源
    最近更新 更多