将项目添加到阵列时,视图不会更新

时间:2014-02-10 15:27:41

标签: knockout.js

背景故事

我正在尝试创建一个页面,我可以使用.NET MVC和Knockout.js编辑创建的投资组合。我的投资组合包含一个或多个投资组合项,而这些项又可以包含0个或更多图像

所以我可以有一个名为“Webdesign”的投资组合,其中包含代表不同客户的投资组合项我为每个客户设计了一个网站,可以有多个图像包含设计的镜头。

在我的视图中使用AJAX我调用.NET MVC控制器,它将我的投资组合投资组合项图像作为JSON返回。 / p>

问题

视图基本上最初工作正常,observable包含正确的数据,所有内容都显示为应该。当我想将图像添加到项目组合项时,会出现此问题。当我单击添加图像(“Voeg een afbeelding toe”)按钮时,将调用addImage函数并将图像推入正确的数组,但视图不会更新。

代码

您将在下面找到细分为最基本的代码,另请参阅底部的工作示例链接。它应该做的是显示已经添加到项目组合项的图像的ID,因此它存在于传入的JSON中,它就是这样。当您单击添加图像按钮(“Voeg afbeelding toe”)时,它应该创建一个新的图像,其ID设置为0,它会更新视图。因此,在您单击添加图像按钮(“Voeg afbeelding toe”)后,您应该看到显示15和0,但这不会发生。

JSON

{"PortfolioId":15,"Title":"test","Text":"\u003cp\u003etest\u003c/p\u003e\n","Image":null,"Published":false,"Created":"maandag 10 februari 2014 14:13","PortfolioItems":[{"PortfolioId":15,"Id":15,"Title":"Titel","Text":"Text","Images":[{"Id":1,"ImageLink":"http://google.nl","ImageLinkTarget":null,"ImageUrl":null}],"Placeholder":null,"Published":false,"SortOrder":19,"Created":"maandag 10 februari 2014 14:13"}]};

的Javascript

function PortfolioEditViewModel() {
    var self = this;
    var json ={"PortfolioId":15,"Title":"test","Text":"\u003cp\u003etest\u003c/p\u003e\n","Image":null,"Published":false,"Created":"maandag 10 februari 2014 14:13","PortfolioItems":[{"PortfolioId":15,"Id":15,"Title":"Titel","Text":"Text","Images":[{"Id":1,"ImageLink":"http://google.nl","ImageLinkTarget":null,"ImageUrl":null}],"Placeholder":null,"Published":false,"SortOrder":19,"Created":"maandag 10 februari 2014 14:13"}]};

    //## PROPERTIES ##
    {
        self.PortfolioId = ko.observable('');
        self.Title = ko.observable('');
        self.Text = ko.observable('');
        self.Image = ko.observable('');
        self.Published = ko.observable('');
        self.Created = ko.observable('');
        self.PortfolioItems = ko.observableArray();        
    }   
    //## SERVICES ##
    {
        //Normally I get this data using Ajax

        self.PortfolioId = json.PortfolioId;
        self.Title = json.Title;
        self.Text = json.Text;
        self.Image = json.Image;
        self.Published = json.Published;
        self.Created = json.Created;
        self.PortfolioItems(json.PortfolioItems);  
    }

    //## FUNCTIONS ##
    self.addPortfolioItem = function () {        
        self.PortfolioItems.push({
            Title: "",
            Text: "",
            Images: ko.observableArray(),
            Placeholder: "",
            Published: false,
            SortOrder: $("#sortable tbody tr").length + 1
        });
    };

    self.addImage = function (item) {
        //Pushes item into array but view doesn't get updated
        item.Images.push({
            Id: 0,
            ImageUrl: "",
            ImageLink: "",
            ImageLinkTarget: ""
        });          
    };

}
var portfolioEditViewModel = null;
function initPortfolioEdit() {
    portfolioEditViewModel = new PortfolioEditViewModel();    
    ko.applyBindings(portfolioEditViewModel, document.getElementById("portfolioEditContainer"));
}
$(document).ready(function(){
    initPortfolioEdit();    
});

查看

<div id="portfolioEditContainer">    
    <section class="contentMain">
        <div class="container">        
            <div class="row">
                <div class="col-lg-12">
                    <table>
                        <tr>
                            <td colspan="2">
                                <table class="width_100 table table-hover" id="sortable">
                                    <tbody data-bind="foreach: {data: PortfolioItems}">
                                        <tr>                                                                               
                                            <td>
                                                <a href="#" class="pzzl-btn" data-bind='click: $root.addImage'>
                                                    <span class="glyphicon glyphicon-plus"></span> <strong>Voeg afbeelding toe</strong>
                                                </a>
                                            </td>
                                        </tr> 
                                        <tr>
                                            <td colspan="2">
                                                <table class="width_100">
                                                    <tbody data-bind="foreach: {data: Images}">                                                        
                                                    <tr>
                                                        <td data-bind="text: Id"></td>
                                                    </tr> 
                                                    </tbody>
                                                </table>                                                            
                                            </td>
                                        </tr>     
                                    </tbody>
                                </table>
                            </td>                                                        
                        </tr>   
                    </table>
                </div>                                                  
            </div>            
        </div>    
    </section>
</div>

JsFiddle

1 个答案:

答案 0 :(得分:2)

您在初始化(PortfolioItems)中添加的self.PortfolioItems(json.PortfolioItems)尚未映射为将Images定义为observableArray。

因此,对于初始数据,Images是一个普通数组,无法通知像observableArray这样的更改。

您希望遍历这些项目,并确保Images是一个observableArray。

以下是映射数组的一种可能解决方案:http://jsfiddle.net/rniemeyer/ffbDs/3/