簡體   English   中英

Knockout JS Binding Null Binding

[英]Knockout JS Binding Null Binding

這是一個小提琴

我有這個HTML:

<div class="margin:0px; padding:0px; outline:0; border:0;" data-bind="with: notesViewModel">
        <table class="table table-striped table-hover" data-bind="with: notes">
            <thead><tr><th>Date Logged</th><th>Content</th><th>Logged By</th><th></th></tr>
            </thead>
            <tbody data-bind="foreach: allNotes">
                <tr>
                    <td data-bind="text: date"></td>
                    <td data-bind="text: compressedContent"></td>
                    <td data-bind="text: logged"></td>
                    <td><img src="/images/detail.png" data-bind="click: $root.goToNote.bind($data, $index())" width="20" alt="Details"/></td>
                </tr>
            </tbody>
        </table>

        <div class="noteView" data-bind="with: chosenNote">
            <div class="info">
                <p><label>Date:</label><span data-bind="text: date"></span></p>
                <p><label>Logged:</label><span data-bind="text: logged"></span></p>
            </div>
            <p class="message" data-bind="html: content"></p>
            <button class="btn btn-default" data-bind="click: $root.toNotes">Back to Notes</button>
        </div>

        <div class="editor-label" style="margin-top:10px">
            Notes
        </div>
        <div class="editor-field">
            <textarea id="contact_note" rows="5" class="form-control" data-bind="value: $root.noteContent"></textarea>
            <p data-bind="text: $root.characterCounter"></p>
            <button class="btn btn-info" data-bind="click: $root.saveNotes">Save</button>
            <div data-bind="html: $root.status">

            </div>   
        </div>
    </div>

這個JavaScript使用淘汰賽:

var notesViewModel = function () { 
    var self = this;
    self.notes = ko.observable(null);
    self.chosenNote = ko.observable();
    self.allNotes = new Array();
    self.user = "user1";
    // behaviours
    self.goToNote = function (noteIndex) {
        self.notes(null);
        self.chosenNote(new note(self.allNotes[noteIndex]));
    };
    self.toNotes = function () {
        self.chosenNote(null);
        self.notes({ allNotes: $.map(self.allNotes, function (item) { return new note(item); }) });
        console.log(self.notes());
    }

    self.noteContent = ko.observable();
    self.saveNotes = function () {
        var request = $.ajax({
            url: "EnquiryManagement/Contact/SaveNotes",
            type: "GET",
            dataType: "json",
            data: { id: "1322dsa142d2131we2", content: self.noteContent() }
        });
        request.done(function (result, message) {
            var mess = "";
            var err = false;
            var imgSrc = "";
            if (message = "success") {
                if (result.success) {
                    mess = "Successfully Updated";
                    imgSrc = "/images/tick.png";
                    self.allNotes.push({ date: new Date().toUTCString(), content: self.noteContent(), logged: self.user });
                    self.toNotes();
                } else {
                    mess = "Server Error";
                    imgSrc = "/images/redcross.png";
                    err = true;
                }
            } else {
                mess = "Ajax Client Error";
                imgSrc = "/images/redcross.png";
                err = true;
            }

            self.status(CRTBL.CreateMessageOutput(err, mess, imgSrc));
            self.noteContent(null);
            setTimeout(function () {
                self.status(null);
            }, 4000);
        });
    };
    self.status = ko.observable();

    self.characterCounter = ko.computed(function () {
        return self.noteContent() == undefined ? 0 : self.noteContent().length;
    });
};

var note = function (data) {
    var self = this;
    console.log(data.date);
    self.date = CRTBL.FormatIsoDate(data.date);
    self.content = data.content;
    self.compressedContent = data.content == null ? "" : data.content.length < 25 ? data.content : data.content.substring(0, 25) + " ...";
    self.logged = data.logged;
    console.log(this);
};

ko.applyBindings(new notesViewModel());

當我第一次加載頁面時,它說:

未捕獲錯誤:無法解析綁定。 消息:ReferenceError:未定義注釋; 綁定值:with:notes

但是,我把它傳遞給null,所以它不應該顯示任何東西,因為當我執行函數goToNote然后執行goToNotes它將可觀察的notes設置為null

那么為什么我不能從這個null值開始呢?

問題在於你有:

<div data-bind="with: notesViewModel">

這使得它在notesViewModel中尋找屬性“notesViewModel”,該屬性不存在。

如果您只有一個視圖模型,則可以刪除該數據綁定,它將正常工作。

但是,如果您希望將視圖模型專門應用於該div而不是整個頁面,請為其提供ID或其他形式的訪問者,並將其添加為applyBindings中的第二個參數,如下所示:

HTML:

<div id="myDiv">

JS:

ko.applyBindings(new notesViewModel(), document.getElementById('myDiv'));

通常只有在同一頁面中有多個視圖模型時才需要這樣做。

就像bcmcfc所說的那樣,由於我的場景是一個多視圖模型場景,我不認為他的解決方案是正確的。

為了達到正確的結果,首先我推斷出self.notes = ko.observable(null); 進入一個viewModel,使得表綁定變得更加容易。

然后修復綁定問題而不是設置綁定發生的元素,我只是這樣做:

ko.applyBindings({
    mainViewModel: new mainViewModel(),
    notesViewModel: new notesViewModel()
});

在我的原始代碼中,我有兩個viewModel,這就是我收到此錯誤的原因。 使用這種方法的關鍵是:

我不創造依賴!

而不是將viewModel綁定到某個dom元素,這個元素可以很容易地改變並導致不得不用ko改變一些東西,再加上如果我添加更多的viewModels那么它會變得更復雜。 我只是這樣做:

data-bind="with: viewModel"

這樣我可以綁定到任何DOM對象,我可以擁有許多我喜歡的對象。

這是解決我的帖子的解決方案。

這是jsfiddle

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM