2013-01-08 86 views
1

讓我們先從代碼..淘汰賽複雜的數據模型綁定

的JavaScript綁定視圖模型,並顯示對話框

$("#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拋出錯誤「Can not read property'title'of null;」當我啓動對話框時。也就是說,「alert(song.title());」實際上顯示了歌曲標題。

有關我哪裏出錯的想法嗎?

更新

我已經創建了一個複製問題的jsfiddle。 http://jsfiddle.net/mcottingham/H7jqa/28/

+1

這ISN」因爲綁定在AJAX調用完成之前發生,所以不起作用。 –

回答

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(); 
    }); 
    } 
}) 

//另一代碼

而在loadfromserver函數的開頭添加return聲明:

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

正是我輸入的答案。 +1以正確處理jqxhr對象。 – jjperezaguinaga

+0

此外,作爲代碼改進,您可以用'ko.applyBindingsToNode(domNode,{template:{name:'manage-song-template'}})'替換'ko.applyBindings(vm,domNode)'。然後你也可以移除'attr('data-bind',...)'方法的調用。這種改變使你的代碼更快更優雅 – Serjio

+0

@Serjio我已經提出了修改,但是,我仍然得到相同的錯誤。警報仍顯示標題文本。 – mcottingham