在淘汰赛中使用JSON时的计算可观察性

时间:2013-08-23 13:33:37

标签: c# knockout.js

我正在听取一些淘汰建议。我已经发布了这个问题,但我的理解已经改变,所以我要重新发布。

我有以下代码:

function updateViewModel() {
    if (typeof groupId == 'undefined') {
        groupId = getDefaultGroupId();
    }

    $.getJSON("api/livestatusgroup/children/" + groupId)
        .done(function (data) {
            ko.mapping.fromJS(data, liveStatusViewModel.groups);
            groupsLoaded();
        });

    $.getJSON("api/livestatusgroup/resources/" + groupId)
        .done(function(data) {
            ko.mapping.fromJS(data, liveStatusViewModel.resources);
            resourcesLoaded();
        });

    this.resourceImagePath = ko.computed(function () {
        return "../Image/" + this.resourceID();
    }, this);
}


function ViewModel() {
    var self = this;
    self.resources = ko.mapping.fromJS([]);
    self.groups = ko.mapping.fromJS([]);
}

我正在使用JSON加载我的视图模型,但是我遇到了resourceID()方法的问题。我不知道如何编写将使用资源ID替换this.resourceID()的方法(例如,.. / Image1)。我试过使用像这样的计算观察器:

    liveStatusViewModel.resources.resourceID() = ko.computed(function() {
        return this.ResID;
    }, liveStatusViewModel);

......但那没用。谁能帮我吗?我已经查看了整个interweb,包括Stack Overflow,但没有运气。这是一个真正的绊脚石!

进一步的工作

我刚尝试改变将/ Image / xx附加到图像src的方式,如下所示:

    function resourceImagePath(resourceId) {
        return "/Images/" + resourceId;
    }

使用以下HTML标记

<div class="icon" id="resourceIcon" runat="server"><img data-bind="attr: { src: resourceImagePath(ResourceId) }" alt=""/></div>

这不起作用。令人讨厌的是,上面的函数resourceImagePath重写如下:

    function resourceImagePath(resourceId) {
        return "/Images/1";
    }

图像ID硬编码进行测试,效果绝对正常。

理想情况下,我想知道如何在我的JSON中观察资源ID。

有没有其他想法?

谢谢,Mark

2 个答案:

答案 0 :(得分:0)

我认为您的结构不正确,因为计算函数“resourceImagePath”应该是单个资源的定义。

我意识到你可能想要使用那个映射插件,但根据我的经验,我发现当我手动映射时我有更多的灵活性。这不好玩,但是你做了一次并继续前进。

以下是我将如何处理这个问题。我根本没有测试过它。

  1. 定义视图模型(“资源”,“组”,“viewModel”; 包括计算变量)

  2. 在文档加载上调用viewModel.Initialize函数

  3. 初始化循环通过JSON结果(即“数据”)调用以收集数据和
    创建Javascript对象的新实例(即“资源”,“组”)

    // global variable
    var groupId;
    
    
    // define view models
    var resource = function(resourceID){
        var self = this;
    
        self.resourceID() = ko.observable(resourceID);
    
        self.resourceImagePath = ko.computed(function () {
                return "../Image/" + self.resourceID();
        }, self);
    }
    
    // define group
    var group = function(groupId){
        var self = this;
        self.groupID() = ko.observable(groupId);
    }
    
    var viewModel = function() {
            var self = this;
            self.resources = ko.observableArray([]);
            self.groups = ko.observableArray([]);
    
            self.Initialize = function(){
    
                if (typeof groupId == 'undefined') {
                        groupId = getDefaultGroupId();
                }
    
                $.getJSON("api/livestatusgroup/children/" + groupId)
                        .done(function (data) {
                                for(var i = 0, j = data.length; i< j; i++){
                                    self.groups.push(new group(data[i].groupID))                            
                                }                                                       
                                groupsLoaded();
                        });
    
                $.getJSON("api/livestatusgroup/resources/" + groupId)
                        .done(function(data) {
                                for(var i = 0, j = data.length; i< j; i++){
                                    self.resources.push(new resource(data[i].resourceID))                           
                                }                                                       
                                resourcesLoaded();
                        });     
    
            }
    
    }
    
    
    var vmContext;
    $(function () {
        vm = new viewModel();
        vm.Initialize();
    });
    

答案 1 :(得分:0)

从一目了然,我看到了一些潜在的问题。

<img data-bind="attr: { src: resourceImagePath(ResourceId) }" />

这里的问题是你在调用resouceImagePath函数时没有解析observable。在直接调用时,您只能使用不带括号的observable,如

<img data-bind="attr: { src: SourceObservable }" />

所以,写它的正确方法是

<img data-bind="attr: { src: resourceImagePath(ResourceId()) }" />

此外,您的计算ResourceID未正确分配。

liveStatusViewModel.resources.resourceID() = ko.computed(function() {
    return this.ResID;
}, liveStatusViewModel);

在这里,您在resourceID上添加了paranthesis,它试图解析该函数​​,同时还尝试在表达式的右侧分配一个值。这不是有效的JavaScript。删除括号后,它应该可以正常工作。

liveStatusViewModel.resources.resourceID = ko.computed(function() {
    return this.ResID;
}, liveStatusViewModel);

至于你的其他帖子,我并不是真正理解你要做的是什么,所以这是我能给出的最佳答案。我不确定您是否要将resourceID分配给liveStatusViewModel.resources上的每个资源,或者您是否要在liveStatusViewModel.resources对象上添加一个。如果你澄清,我将能够进一步回答。