淘汰复杂数据模型绑定

时间:2013-01-08 20:56:38

标签: javascript jquery knockout.js

让我们从代码开始..

Javascript绑定viewmodel并显示对话框

$("#add-song").click(function () {
    $("<div>")
        .attr("data-bind", "template: { name: 'manage-song-template' }")
        .dialog({
            resizable: false,
            modal: true,
            title: "Add Song",
            width: 960,
            height: 490,
            buttons: [
                {
                    text: "Create Song",
                    'data-bind': 'click: savechanges',
                    click: function () {

                    }
                },
                {
                    text: "Close",
                    click: function () {
                        $(this).dialog("close");
                    }
                }
            ],
            close: function () {
                $(this).dialog('destroy').remove();
            },
            open: function () {
                ko.applyBindings(new my.managesongviewmodel());
                jquerybindings();
            }
        });        
});

现在让我们看一下视图模型

my.managesongviewmodel = function () {
    var
        //Scalar Properties
        song = null,

        //Functions
        loadfromserver = function (Id) {
            $.post("/song/getsong", "id=1", function (response) {
                if (response.Success) {
                    var data = response.Data;
                    var song = response.Data.Song;

                    var songdata = {
                        Song: {
                            Id: song.Id,
                            Title: song.Title,
                            Description: song.Description,
                            Lyrics: song.Lyrics,
                            isMaster: song.isMaster,
                            AudioFilePath: song.AudioFilePath,
                            CoverImageFilePath: song.CoverImageFilePath,
                            CreatedDate: song.CreatedDate
                        },
                        Genres: data.Genres,
                        SongAlternateTitles: data.SongAlternateTitles,
                        Exploitations: data.Exploitations,
                        SongWriterSongs: data.SongWriterSongs
                    };                        
                    song = new my.song(songdata);
                    alert(song.title());
                }
            });
        },

        savechanges = function () {
        };

    loadfromserver();
    return {
        song: song,
        loadfromserver: loadfromserver
    };
};

my.song = function (data) {
    var
        //Scalar Properties
        id = ko.observable(data.Song.Id),
        title = ko.observable(data.Song.Title),
        description = ko.observable(data.Song.Description),
        lyrics = ko.observable(data.Song.Lyrics),
        ismaster = ko.observable(data.Song.isMaster),
        audiofilepath = ko.observable(data.Song.AudioFilePath),
        coverimagefilepath = ko.observable(data.Song.CoverImageFilePath),
        createddate = ko.observable(data.Song.CreatedDate),

        //Arrays
        genres = ko.observableArray(data.Genres),
        alttitles = ko.observableArray(data.SongAlternateTitles),
        exploitations = ko.observableArray(data.Exploitations),
        songwritersongs = ko.observableArray(data.SongWriterSongs);

    return {
        id: id,
        title: title,
        description: description,
        lyrics: lyrics,
        ismaster: ismaster,
        audiofilepath: audiofilepath,
        coverimagefilepath: coverimagefilepath,
        createddate: createddate,

        genres: genres,
        alttitles: alttitles,
        exploitations: exploitations,
        songwritersongs: songwritersongs
    };
};

这是我的模板

<script type="text/html" id="manage-song-template">
    <div class="modal-form">
        <span data-bind="text: song.title"></span>
    </div>
</script>

Chrome正在抛出错误“无法读取属性'标题'的null;”当我启动对话框时。那说,“警报(song.title());”实际上显示了歌曲的标题。

关于我哪里出错了?

更新

我创建了一个复制问题的jsfiddle。 http://jsfiddle.net/mcottingham/H7jqa/28/

1 个答案:

答案 0 :(得分:5)

这很容易。在您显示模态窗口的那一刻,您的歌曲var仍然等于null。因此,您必须等待从服务器加载有关歌曲的信息:

$("<div>").attr("data-bind", "template: { name: 'manage-song-template' }").dialog({
   // another options
   open: function (event, ui) {
     var vm = new my.managesongviewmodel(), domNode = this;
     vm.loadfromserver().done(function() {
       ko.applyBindings(vm, domNode);
       jquerybindings();
     });
   }
})

//另一个代码

return函数的开头添加loadfromserver语句:

loadfromserver = function (Id) {
   return $.post("/song/getsong", "id=1", function (response) {
    // code
   });
}