无法处理绑定,未定义国家/地区

时间:2016-02-05 09:48:38

标签: javascript knockout.js typescript

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

  

未捕获的ReferenceError:无法处理绑定“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>

可行,但<select>在选择框中显示[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>

它有效,但我在<select>中没有任何值,因为我已经摆脱了javascript对象的数组并使它成为一个字符串数组。

如何在不抱怨_countries未定义的情况下将javascript对象数组绑定到<select>?是不是因为我在文档准备好之后进入_countries数组,而在html中我在加载文档之前绑定了ko.observableArray?如果是这样,我确实尝试使用值初始化ko.observableArray,但它没有解决问题。

1 个答案:

答案 0 :(得分:1)

使用Rohith的回答。只是为了进一步详细说明,导致错误的不是_countries,而是这些optionsText: country.countryName, value: country.geonameId,您的viewmodel不知道任何国家/地区,这些值位于_countries可观察数组中。并且您使用options数据绑定参数的方式不正确。

检查docs以获取有关此绑定的更多详细信息。

为了满足您的需求,首先您使用optionsText,该值的值应为'countryName'。然后对于value,这将是包含所选选项的observable。因此,在您的viewmodel中,您需要添加countryselectedCountry之类的内容或您喜欢的名称。

要将其置于代码中,您的更改将是这样的。 更改viewmodel:

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>