开发者

KnockoutJS: template is not updated on observable array change (only on add, works on remove)

So, I have observable array with sites, which is shown via template. If I'll add site to this array, template is not updated, but if I'll remove site from array – voila! template became updated and all previously added sites became displayed too.

If I'll use nifty hack (commented in code) with replacement of whole array to new one then everything works.

BTW, I load template via AJAX and use "ko.applyBindings(viewModel)" after. I assume that works fine, because initial sites are displayed correctly.

$(function(){

//site entry in user's sites list
var siteObject = function(url, lastChecked, status){
    this.url = url;
    this.lastChecked = (lastChecked == 'undefined') ? '' : lastChecked;
    this.status = (status == 'undefined') ? 'not_checked_yet' : status;
    this.toDelete = false;
    this.remove = function() {viewModel.sites.remove(this)};
};

viewModel = {
    //=========== sites list managment ==========================
    sites: ko.observableArray(),
    //on "add" click in "add site" form
    addSite: function(){
        var $form = $('#add_site_form');
        var siteUrl = $form.find('input[name="site"]').val();

        /*nifty hack  <----
        var sites = this.sites();
        sites.push(new siteObject(siteUrl));
        this.sites(sites);*/

        this.sites.push(new siteObject(siteUrl));
    },
    //on "remove sites" button click
    removeSites: function() {
        var sitesToRemove = [];
        $.each(this.sites(), function(){
            if (this.toDelete) sitesToRemove.push(this);
        });
        if (sitesToRemove.length == 0)
     开发者_StackOverflow社区       alert("Ни одного сайта не было выбрано для удаления.");
        else {
            var message = "Вы точно хотите перестать отслеживать";
            for (var i in sitesToRemove) {
                message += "\n\"" +  sitesToRemove[i].url + "\"";
            }
            message += "?";
            if (confirm(message)) {
                $.each(sitesToRemove, function(){this.remove()});
                //save new sites list to db
                this.saveSitesListToDb();
            }
        }   
        //hide form
        $('#remove_sites_form').slideToggle();
        //toggle checkboxes
        $('#content_sites_list .site_info input[type="checkbox"]').slideToggle();
    };

And the template:

<!-- end of menu -->
<div id="content_sites_list" 
     class="grid_12" 
     data-bind="template: {name: 'sites_list_template', foreach: sites}"></div>

  <!-- Templates -->

  <script id="sites_list_template" type="text/x-jquery-tmpl">
    <div class="site">
        <div class="site_panel grid_12">
            <div class="site_info">
                &ndash;
                <input type="checkbox" value="${url}" 
                       class="delete_checkbox" data-bind="checked: toDelete" /> 
                <a href="${url}" class="show_site_stat">${url.substr(7)}</a>
                {{if status == "200"}}
                    <img src="img/green_light.png" alt="ok"/>
                {{/if}}             
            </div>
            <div class="site_stat">
                <div class="site_last_check">Последняя проверка: ${dateTimestamp}</div>
            </div>
        </div>
    </div>
  </script>

I've tried this on latest beta on knockoutjs and on stable one.


I have made a jsFiddle which works fine.

There were some problems that JSLint was complaining about in the removeSites function of the viewModel. I fixed those and added a button and input field to be able to give some input, and everything ran smooth.

So you could try updating your removeSites function and see if it helps you,

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜