如何让这个jsfiddle示例工作?

时间:2012-04-01 11:27:35

标签: knockout.js jsfiddle

我一直试图让this jsfiddle工作。到目前为止没有运气。

我编写(复制)的HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta name="generator" content=
  "HTML Tidy for Linux/x86 (vers 11 February 2007), see www.w3.org" />
  <!-- add some head tags here -->

  <title>Try</title>
  <script src="http://code.jquery.com/jquery-1.7.2.min.js" type="text/javascript">
</script>
  <script type="text/javascript" src=
  "http://rniemeyer.github.com/KnockMeOut/Scripts/knockout-latest.debug.js">
</script>
  <script type="text/javascript" src="static/js/knockout.mapping.js">
</script>
  <style type="text/css">
/*<![CDATA[*/
  body, a, p { font-size: .85em; }
  input { width: 100px; }
  table { border: 1px solid black; }
  h3, p, td, th { padding: 3px; }
  h3 { font-weight: bold; }
  .matched { background-color: yellow; }
  .n { text-align: right; }
  /*]]>*/
  </style>
</head>

<body>
  <script type="text/javascript" src="static/js/array_mapping.js">
</script><script type="text/javascript" src=
"https://raw.github.com/jquery/jquery-tmpl/master/jquery.tmpl.min.js">
</script>

  <h3>1- JSON string from server</h3>

  <p data-bind="text: JSONdataFromServer"></p>

  <h3>2- Converted to an object with ko.parseJSON</h3>

  <p data-bind="text: ko.toJSON(dataFromServer)"></p>

  <h3>3- Mapped to use observables and add a dependentObservable</h3>

  <p data-bind="text: ko.toJSON(mappedData)"></p>
  <hr />

  <h3>4- Display in an editor</h3><script id="itemsTmpl" type="text/html">
<![CDATA[
        <tr data-bind="css: { matched: $data === viewModel.firstMatch() }">
            <td>
                <input data-bind="value: name" />
            </td>
            <td>
                <select data-bind="options: viewModel.categories, value: category"></select>
            </td>
            <td>
                <input class="n" data-bind="value: price" />
            </td>
            <td class="n" data-bind="text: priceWithTax">
            </td>
            <td>
                <a href="javascript: void(0);" data-bind="click: function() { viewModel.removeItem($data); }">Delete</a>
            </td>
        </tr>
  ]]>
  </script>

  <table id="mytable" data-bind="triggerUpdate: items">
    <thead>
      <tr>
        <th>Name</th>

        <th>Category</th>

        <th>Price</th>

        <th>w/Tax</th>

        <th></th>
      </tr>
    </thead>

    <tr>
      <td><a href="javascript:%20void(0);" data-bind="click: addItem">Add Item</a></td>

      <td></td>

      <td class="n">Total:</td>

      <td class="n" data-bind="text: total"></td>

      <td></td>
    </tr>
  </table>

  <h3>5- Filter display by name</h3>

  <p>Filter: <input data-bind="value: filter, valueUpdate: 'afterkeydown'" /></p>

  <h3>6- Find first match by name</h3>

  <p>Search: <input data-bind="value: search, valueUpdate: 'afterkeydown'" /></p>
  <hr />

  <h3>7- Use ko.utils.arrayMap to build an array with just categories used</h3>

  <p data-bind="text: ko.toJSON(viewModel.justCategories)"></p>

  <h3>8- Use ko.utils.arrayGetDistinctValues to get just the unique categories used</h3>

  <p data-bind="text: ko.toJSON(viewModel.uniqueCategories)"></p>

  <h3>9- Use ko.utils.compareArrays to find available categories that haven't been
  used</h3>

  <p data-bind="text: ko.toJSON(viewModel.missingCategories)"></p>

  <h3>10- Convert items to JSON</h3>

  <p data-bind="text: ko.toJSON(viewModel.items)"></p>

  <h3>11- Map items to send back to server and convert to JSON</h3>

  <p data-bind="text: ko.toJSON(viewModel.mappedItems)"></p>
</body>
</html>

javascript位于一个名为array_mapping.js的文件中,看起来像这样

    function Item(name, category, price) {
        this.name = ko.observable(name);
        this.category = ko.observable(category);
        this.price = ko.observable(price);
        this.priceWithTax = ko.dependentObservable(function() {
            return (this.price() * 1.05).toFixed(2);
        }, this);
    }

    var viewModel = {
        categories: ["Bread", "Dairy", "Fruits", "Vegetables"],
        items: ko.observableArray([]),
        filter: ko.observable(""),
        search: ko.observable(""),
        addItem: function() {
            this.items.push(new Item("New", "", 1));
        },
        removeItem: function(item) {
            this.items.remove(item);
        }
    };

    //ko.utils.arrayFilter - filter the items using the filter text
    viewModel.filteredItems = ko.dependentObservable(function() {
        var filter = this.filter().toLowerCase();
        if (!filter) {
            return this.items();
        } else {
            return ko.utils.arrayFilter(this.items(), function(item) {
                return ko.utils.stringStartsWith(item.name().toLowerCase(), filter);
            });
        }
    }, viewModel);


    //ko.utils.arrayForEach - return a total by adding all prices
    viewModel.total = ko.dependentObservable(function() {
        var total = 0;
        ko.utils.arrayForEach(this.filteredItems(), function(item) {
            var value = parseFloat(item.priceWithTax());
            if (!isNaN(value)) {
                total += value;
            }
        });
        return total.toFixed(2);
    }, viewModel);


    //ko.utils.arrayFirst - identify the first matching item by name
    viewModel.firstMatch = ko.dependentObservable(function() {
        var search = this.search().toLowerCase();
        if (!search) {
            return null;
        } else {
            return ko.utils.arrayFirst(this.filteredItems(), function(item) {
                return ko.utils.stringStartsWith(item.name().toLowerCase(), search);
            });
        }
    }, viewModel);

    //ko.utils.arrayMap - get a list of used categories
    viewModel.justCategories = ko.dependentObservable(function() {
        var categories = ko.utils.arrayMap(this.items(), function(item) {
            return item.category();
        });
        return categories.sort();
    }, viewModel);

    //ko.utils.arrayGetDistinctValues - get a unique list of used categories
    viewModel.uniqueCategories = ko.dependentObservable(function() {
        return ko.utils.arrayGetDistinctValues(viewModel.justCategories()).sort();
    }, viewModel);

    //ko.utils.compareArrays - find any unused categories
    viewModel.missingCategories = ko.dependentObservable(function() {
        //find out the categories that are missing from uniqueNames
        var differences = ko.utils.compareArrays(viewModel.categories, viewModel.uniqueCategories());
        //return a flat list of differences
        var results = [];
        ko.utils.arrayForEach(differences, function(difference) {
            if (difference.status === "deleted") {
                results.push(difference.value);
            }
        });
        return results;
    }, viewModel);

    //ko.utils.arrayMap - prepare items to be sent back to server
    viewModel.mappedItems = ko.dependentObservable(function() {
        var items = ko.toJS(this.items);
        return ko.utils.arrayMap(items, function(item) {
            delete item.priceWithTax;
            return item;
        });
    }, viewModel);

    //a JSON string that we got from the server that wasn't automatically converted to an object
    var JSONdataFromServer = '[{"name":"Peach","category":"Fruits","price":1},{"name":"Plum","category":"Fruits","price":0.75},{"name":"Donut","category":"Bread","price":1.5},{"name":"Milk","category":"Dairy","price":4.50}]';

    //parse into an object
    var dataFromServer = ko.utils.parseJson(JSONdataFromServer);

    //do some basic mapping (without mapping plugin)
    var mappedData = ko.utils.arrayMap(dataFromServer, function(item) {
        return new Item(item.name, item.category, item.price);
    });

    viewModel.items(mappedData);

    ko.applyBindings(viewModel);

脚本部分中的所有链接都正常工作。但我无法得到理想的结果。

我注意到如果我在框架菜单上尝试其他任何选项(例如onLoad),代码也不会在jsfiddle上运行。这可能是个原因吗?

1 个答案:

答案 0 :(得分:0)

HTML中引用viewModel的任何绑定都将其用作全局变量。所以,当你做onLoad时,它不会是全局的。使用KO 2.0,您现在可以将viewModel替换为$root,而viewModel则不需要是全局的。我会从https://github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.debug.js

获取KO的更新版本

此外,任何调用ko.applyBindings的代码都应放在页面底部或类似jQuery&#34; ready&#34;功能,因为它需要完整的DOM。因此,您可以将外部js文件放在页面底部。