【问题标题】:Knockout JS Binding Null Binding淘汰赛JS绑定空绑定
【发布时间】:2014-02-11 06:31:43
【问题描述】:

这是fiddle

我有这个 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:注释

但是,我将它传递给 null,所以它不应该显示任何内容,因为当我执行函数 goToNote 然后执行 goToNotes 时,它会将 notes 可观察值设置为 null

那么为什么我不能从这个null 值开始呢?

【问题讨论】:

  • 你能用小提琴重新创建这个吗?此外,如果您正在实例化视图模型,您是否尝试过使其成为匿名函数而不是分配给变量的函数?这听起来可能不对,但是使用函数 notesViewModel 而不是 var notesViewModel = function 进行成像,或者在 applyBindings 中不使用 new。我将您的代码放入小提琴中,如果您删除 with: notesViewModel 绑定,它看起来可以按预期工作...
  • 不知道这是否是您出错的原因,但if (message = "success") 应该是if (message === "success")。另外,您应该使用=== 进行比较。
  • @PWKad 将小提琴链接添加到 OP

标签: javascript knockout.js


【解决方案1】:

问题出在哪里:

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

这使它在您的 notesViewModel 中查找属性“notesViewModel”,该属性不存在。

如果您只有一个视图模型,您可以删除该数据绑定,它会正常工作。

但是,如果您希望将您的视图模型专门应用于该 div 而不是整个页面,请给它一个 ID 或其他形式的访问器,并将其添加为 applyBindings 中的第二个参数,如下所示:

HTML:

<div id="myDiv">

JS:

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

这通常只有在同一页面中有多个视图模型时才需要。

【讨论】:

  • 是的,我已经解决了这个问题,所以我的假设是,如果您每页有多个 viewModel,最好这样做:ko.applyBindings({ mainViewModel: new mainViewModel(), notesViewModel: new notesViewModel}) 现在我遇到另一个错误,请参阅fiddle
  • 你的新问题是完全无关的——它告诉你控制台出了什么问题...
  • $root.notesViewModel.goToNote.bind($data, $index())
  • 事实证明它不需要修复,我清除了控制台,刷新了页面,它工作得非常好,但是,我仍然喜欢你的评论,因为它展示了如何在多视图模型场景中访问某些视图模型
【解决方案2】:

就像 bcmcfc 所说的那样,但是,由于我的场景是多视图模型场景,我认为他的解决方案不太正确。

为了获得正确的结果,首先我将self.notes = ko.observable(null); 外推到一个视图模型中,这使得表格绑定变得更加容易。

然后为了解决绑定问题而不是设置一个元素来进行绑定,我只是这样做了:

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

在我的原始代码中,我有两个 viewModel,这就是我收到此错误的原因。这种方法的关键是:

我不创建依赖关系!

而不是将 viewModel 绑定到某个 dom 元素,该元素可以很容易地更改并导致不得不使用 ko 进行更改,另外,如果我添加更多 viewModel,那么它会变得更加复杂。我只是这样做:

data-bind="with: viewModel"

这样我可以绑定到任何 DOM 对象,并且我可以拥有许多我喜欢的对象。

这是解决我帖子的解决方案。

这里是jsfiddle

【讨论】:

    猜你喜欢
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 2014-03-30
    • 1970-01-01
    • 2013-02-04
    • 2014-10-30
    • 2013-10-31
    相关资源
    最近更新 更多