2014-10-30 50 views
1

我需要在執行後臺任務(使用JQuery promise)時顯示加載gif。我有大部分代碼,但是我的問題如下:Knockout.js:如何在完成異步調用時顯示加載圖像

問題:加載gif顯示在數據準備好顯示時,這違背了使用加載gif的目的!如何在開始時正確顯示gif,然後在數據準備好顯示之後將其刪除。

我正在使用帶有可觀察標誌的KO的自定義綁定處理程序。

你可以看到在這個jsfiddle

的JavaScript代碼:

ko.bindingHandlers.loadingList = { 

    init: function (element, valueAccessor) { 
     ko.utils.unwrapObservable(valueAccessor()); 
     if (valueAccessor() == true) { 
      $(element).wrap($('<div>', { 
       "class": "loading" 
      })); 
      $(element).before($('<div>', { 
       "class": "loading_inner" 
      })); 
     } else { 
      $(element).parent().replaceWith($(element)); 
     } 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor) { 
     ko.utils.unwrapObservable(valueAccessor()); 
     if (valueAccessor() == true) { 
      $(element).wrap($('<div>', { 
       "class": "loading" 
      })); 
      $(element).before($('<div>', { 
       "class": "loading_inner" 
      })); 
     } else { 
      $(element).parent().replaceWith($(element)); 
     } 
    } 
}; 


function PersonViewModel(callback) { 
    var self = this; 

    self.InProgress = ko.observable(true); 
    self.persons = ko.observableArray([]); 

    // Get available audits 

    var promises = []; 
    promises.push(GetPersons()); 

    $.when.apply($, promises).then(function() { 
     self.persons(arguments[0]); 
     self.InProgress(false); 
    }); 
} 

ko.applyBindings(new PersonViewModel()); 

function GetPersons() { 

    var dfrd = $.Deferred(); 

    var result = [{ 
     Name: 'John Smith', 
     Country: 'USA' 
    }, { 
     Name: 'Juan Carlos', 
     Country: 'Spain' 
    }]; 

    setTimeout(function() { 
     dfrd.resolve(result) 
    }, 3000); 

    return dfrd; 
} 

HTML:

<div class="container"> 
    <h1>Persons</h1> 

    <hr /> 
    <table data-bind="foreach: persons, loadingList:InProgress()"> 
     <thead> 
      <tr> 
       <th><span>Name</span> 

       </th> 
       <th><span>Country</span> 

       </th> 
      </tr> 
     </thead> 
     <tbody> 
      <tr> 
       <td><span data-bind="text:Name"></span> 

       </td> 
       <td><span data-bind="text:Country"></span> 

       </td> 
      </tr> 
      <td> 
    </table> 
</div> 

回答

1

我只是編輯您的更新代碼與此

setTimeout(function(){$(element).parent().parent().replaceWith($(element));}, 1000); 

設置超時只是爲了檢查是否加載時出現 http://jsfiddle.net/zL8vtwsa/30/

按你的意見,我試了一下四周與一個容器較少的綁定顯示,我認爲這將用於此目的

http://jsfiddle.net/zL8vtwsa/78/

<tbody> 
      <!-- ko foreach:persons --> 
      <!-- /ko --> 
    </tbody> 
+0

謝謝Rohith Nair的幫助。我給你一個投票。如何在開始時顯示加載gif?正如我在文章中提到的那樣,gif正在顯示,就像數據準備好顯示一樣。 – user1309226 2014-10-30 11:32:37

+0

@ user1309226我已更新答案 – 2014-10-30 12:10:04

+0

完美無缺! – user1309226 2014-10-30 19:52:36

2

在您的更新方法的代碼替換父DIV(。加載),但不會刪除它之前的元素(.loading-inner)順便說一句,是在.loading div之外插入的。

else { 
    $(element).parent().replaceWith($(element)); 
} 

所以它似乎加載微調只是被添加到錯誤的地方,我用.prepend而不是.before固定它,看到它在這裏的行動:http://jsfiddle.net/2x6wx6wa/2/

其他一些

位。 GetPersons函數應該返回return dfrd.promise()使它不可變,當第一次運行這個代碼時,Create/Update都會被應用,如果加載微調器已經被追加,檢查你的更新方法。

編輯:

加載微調不會在因爲下面的CSS的開始所示,當去除它工作正常:

.loading { 
    display: table; 
    position: relative; 
} 

/前使用前置相反的,我我們添加了一個檢查來確保加載div只添加一次,這在更接近的檢查中被證明是「真正的」潛在問題。見此處所做的更改:http://jsfiddle.net/tkvvjutx/

+0

謝謝Dead.Rabit。我檢查了你的代碼和兩件事情:首先,加載gif並沒有在開始時顯示,而是隻顯示數據。其次,在數據被替換之後,gif不會被刪除。 – user1309226 2014-10-30 11:46:06