knockoutJS中的三向绑定?可能吗?

时间:2016-01-14 09:21:19

标签: javascript knockout.js

我在下面编写了这段代码,但我无法理解如何将编辑后的值绑定到表中。所以我的问题是:

  1. 当我点击"编辑"按钮,出现对话窗口并显示
    我在对话框输入中的表中给出了值。
  2. 我编辑了这些值。
  3. 我点击接受按钮
  4. 我的新(已修改)值保存在localStorage和表格下方的输出中(h3文本),但它们不会更改表格中的值, 在您重新加载页面之前
  5. 所以,我的问题是:为什么我的代码不替换表中的值而不重新加载页面?

    book.name = self.editor.name();
    book.author = self.editor.author();
    book.genre = self.editor.genre();
    

    完整的代码段:

    var books = [
        {
            id : 1,
            name : "Javascript",
            author : "David Flanagan",
            genre : "learning",
            price : "100"
        },
        {
            id : 2,
            name : "PHP",
            author : "Luke Welling",
            genre : "learning",
            price : "120"
        },
        {
            id : 3,
            name : "Learning JavaScript Design Patterns",
            author : "Addy Osmani",
            genre : "learning",
            price : "400"
        },
        {
            id : 4,
            name : "Understanding ECMAScript 6",
            author : "Nicholas C. Zakas",
            genre : "learning",
            price : "204"
        },
        {
            id : 5,
            name : "Programming JavaScript Applications",
            author : "Eric Elliot",
            genre : "learning",
            price : "214"
        },
        {
            id: 6,
            name : "The C Programming Language",
            author : "Brian W. Kernighan",
            genre : "learning",
            price : "514"
        },
        {
            id : 7,
            name : "Programming Pearls",
            author : "Jon L. Bentley",
            genre : "learning",
            price : "114"
        },
        {
            id : 8,
            name : "Java Concurrency in Practice",
            author : "Brian Goetz",
            genre : "learning",
            price : "140"
        }
    ];
    var idNumber;
    for (var i = 0; i < books.length; i++) {
        idNumber = books.length
    }
    function Book(id, name, author, genre) {
        this.id = ko.observable(id);
        this.name = ko.observable(name);
        this.author = ko.observable(author);
        this.genre = ko.observable(genre);
    }
    var bookModel = function (books) {
        var self = this;
        var rowId;
        self.books = ko.observableArray(books);
    
        self.total = ko.computed(function () {
            var total = 0;
            for (var i = 0; i < self.books().length; i++) {
                total = total + +self.books()[i].price;
            }
            return total.toFixed(2);
        });
    
        self.addBook = function () {
            idNumber += 1;
            console.log(idNumber);
            self.books.push({
                id: idNumber,
                name: '',
                author: '',
                genre: '',
                price: ''
            });
    
        };
    
        self.removeBook = function (book) {
            self.books.remove(book);
            rowId = book.name;
            console.log(rowId);
            updateLocalStorage();
        };
    
        self.editor = new Book();
    
        //self.editBook = function (book) {
        self.editItem = function (book) {
            // populate editor values
            self.editor.id(book.id);
            self.editor.name(book.name);
            self.editor.author(book.author);
            self.editor.genre(book.genre);
    
            // create dialog
            $('#editDisplay').dialog({
                modal: true,
                resizable: false,
                width: 400,
                buttons: {
                    Accept: function () {
                        $(this).dialog("close");
                        book.name = self.editor.name();
                        book.author = self.editor.author();
                        book.genre = self.editor.genre();
    
                        console.log(book);
                        localStorage.setItem("table", JSON.stringify(books));
                        $('#outputName').text(book.name)
                        $('#outputAuthor').text(book.author)
    
                        //location.reload()
                    },
                    Cancel: function () {
                        $(this).dialog("close");
                    }
                }
            });
        };
    
        //};
    
    
        function updateLocalStorage() {
            var localBook = JSON.parse(localStorage['table']);
            for (var i = 0; i < localBook.length; i++) {
                if (localBook[i].name == rowId) {
                    localBook.splice(i, 1);
                    localStorage.setItem("table", JSON.stringify(localBook));
                    break;
                }
            }
        }
    
    
        self.save = function () {
            localStorage.setItem("table", JSON.stringify(books));
        };
    };
    
    
    if (localStorage['table'] == '[]') {
        localStorage.clear();
    }
    
    if (localStorage['table'] !== undefined) {
        var local = JSON.parse(localStorage['table']);
        var viewModel = new bookModel(local);
    
    }
    else {
        var viewModel = new bookModel(books);
        localStorage.setItem("table", JSON.stringify(self.books));
    }
    
    ko.applyBindings(viewModel);
    

    And my jsFiddle

1 个答案:

答案 0 :(得分:2)

当您首次通过实例化book.name创建viewModel时,

bookModel不是可观察的。

看到你传递一个带有静态对象的数组(我的意思是它们的属性是不可观察的):

self.books = ko.observableArray(books);

因此,当您应用绑定时,tds绑定到静态值。

您可以尝试使用Book构造函数构建具有可观察属性的书籍。 E.g。

self.books = ko.observableArray(books.map(function (book) {
    return new Book(book);
}));

然后在编辑完本书之后,您就可以更新图书的可观察属性,如下所示:

book.name(self.editor.name());
book.author(self.editor.author());
book.genre(self.editor.genre());

这就是想法,当然你需要仔细实施它。