0

我的问题是,当我单击使用 observableArray 显示的 href 标记时,它不会刷新我的 UI。我必须使用列表控件。

我有一个显示 6 个文件夹的列表控件,然后是一个显示相同 6 个文件夹和 6 个 href 标签的表格。当我更改列表框控件中的选择时,文件会被刷新,非常轻松流畅。但是,我想/需要使用 href 标签刷新这些文件。如果有人有任何答案,请告诉我。

我已经从这个位置获取了示例中的大部分代码: knockout tutorial


Java 脚本文件“proto.js”:

    var folders = [
    { name: "Folder 3", fileNames: ['File 3_1', 'File 3_2', 'File 3_3']},
    { name: "Folder 4", fileNames: ['File 4_1', 'File 4_4', 'File 4_2', 'File 4_3'] },
    { name: "Folder 5", fileNames: ['File 5_1', 'File 5_4', 'File 5_5', 'File 5_2', 'File 5_3'] },
    { name: "Folder 6", fileNames: ['File 6_1', 'File 6_4', 'File 6_6', 'File 6_5', 'File 6_2', 'File 6_3'] },
    { name: "Folder 2", fileNames: ['File 2_2', 'File 2_1'] },
    { name: "Folder 1", fileNames: ['File 1_1'] }
];

var FileExplorerViewModel = function (lists, selectedList) {
    this.folders = ko.observableArray(lists);

    this.editingList = {
        name: ko.observable(selectedList),
        fileNames: ko.observableArray()
    };

    this.changeFolder = ko.computed({
        read: function () {
            alert("changeFolder: Read");
            return this.editingList;
        },
        write: function (folder) {
            alert("changeFolder: write");
            alert(folder.name);
            if (folder && this.editingList) {
                alert("changeFolder: Write executing");
                selectedList = folder.name;
            }
        },
        owner: this //FileExplorerViewModel
    }, this);

    this.sortFolders = function () {
        this.folders.sort(function (a, b) {
            return a.name < b.name ? -1 : 1;
        });
    };
    this.sortFiles = function () { 
        this.editingList.fileNames.sort(function (a, b) { 
            return a < b ? -1 : 1; 
        }); 
    };

    this.findSavedList = function (name) {
        var lists = this.folders();
        return ko.utils.arrayFirst(lists, function (list) {
            return list.name === name;
        });
    };

    ko.computed(function () {
        //alert("ko.computed");
        // Observe viewModel.editingList.name(), so when it changes (i.e., user selects a different list) we know to copy the saved list into the editing list
        var savedList = this.findSavedList(this.editingList.name());
        if (savedList) {
            var userNamesCopy = savedList.fileNames.slice(0);
            this.editingList.fileNames(userNamesCopy);
        } else {
            this.editingList.fileNames([]);
        }
    }, this);

};

$(document).ready(function () {
    ko.applyBindings(new FileExplorerViewModel(folders, "Folder 4"));
});

HTML 文件:“proto.html”

<!

DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8" />
    <title>File Explorer Prototype</title>
    <link rel="stylesheet" type="text/css" href="css/jquery.mobile-1.1.0.css" />
    <script type="text/javascript" src="../cordova-1.6.0.js"></script>
    <script type="text/javascript" src="../jquery-1.7.2.min.js"></script>
    <script type="text/javascript" src="scripts/knockout-2.0.0.js"></script>
    <script type="text/javascript" src="Proto.js"></script>
</head>
<body class="homeBody">

    <div class='listChooser'>
        <!--<button data-bind='click: deleteList, enable: editingList.name'>Delete</button>
        <button data-bind='click: saveChanges, enable: hasUnsavedChanges'>Save</button>-->
        <!--<select data-bind='options: folders, optionsValue: "name", value: editingList.name'> </select>-->
        <select multiple="multiple" data-bind="options: folders, optionsValue: 'name', value: editingList.name"></select>
        <button data-bind='click: $root.sortFolders'>Sort Folders</button>
        <table>
            <tbody data-bind="foreach: folders">
                <tr><td>
                    <span data-bind="text: name"></span>
                    <a href="#" data-bind="click: $root.changeFolder">Change</a>&nbsp;&nbsp;&nbsp;
                    <!--<a data-bind="attr: {href: name}, click: $root.changeFolder">Change Folder</a>-->
                    <br />
                    </td></tr>
            </tbody>
        </table>
    </div>

    <p>Currently viewing <b><font color="red"><span data-bind='text: editingList.fileNames().length'></span></font></b> file(s) from folder <b><font color="red"><span data-bind="text: editingList.name"></span></font></b>:</p>
    <button data-bind='click: $root.sortFiles'>Sort Files</button>
    <div data-bind='with: editingList'>
        <ul data-bind='foreach: fileNames'>
            <li>
                <div data-bind="text: $data"> </div>
            </li>
        </ul>
    </div>
</body>
</html>

4

1 回答 1

0

您计算的所有 changeFolder 在 write is 时都在做selectedList = folder.name,但这不会影响其他任何事情。我想也许您打算这样做:this.editingList.name(folder.name)相反。这是它的工作原理:http: //jsfiddle.net/antishok/KXhem/44/

这是可行的,但只需进行一些更改,它可能会更简单。不要基于您当前正在工作的文件夹的名称,而是基于文件夹本身。您应该很少需要使用optionsValue绑定,因为使用它意味着覆盖默认功能,即 KO 将每个选项映射到实际对象并将实际对象标识用作“值”。我还将计算更改为简单的订阅,并简化了changeFolder函数 - 没有理由让它成为可写计算。更新小提琴:http: //jsfiddle.net/antishok/KXhem/45/

于 2012-09-30T02:35:30.340 回答