0

我认为这里有些不对劲。我想添加一个ko.computed这样的ko.observableArray

在此之前我的模型清晰

//var job = @Html.Raw(Json.Encode(Model.job));
//var customer = @Html.Raw(Json.Encode(Model.customer));
//var estimateMaterials = @Html.Raw(Json.Encode(Model.estimateMaterials));
//var estimate = @Html.Raw(Json.Encode(Model.estimate));
var estimateTasks = @Html.Raw(Json.Encode(Model.Tasks));

var JobPostViewModel = function(){
    var self = this;
    //self.customer = ko.observable(customer);
    //self.job = ko.observable(job);
    //self.estimateMaterials = ko.observableArray(estimateMaterials);
    //self.estimate = ko.observable(estimate);
    self.estimateTasks = ko.observableArray(estimateTasks);
    self.estimateTasks().estLaborSubTotal = ko.computed(function () {
        return (isNaN(self.EstHr)? 0: +self.EstHr) * (isNaN(self.TaskPerHourCost)? 0: +self.TaskPerHourCost);
    });
};
var model = new JobPostViewModel();
ko.applyBindings(model,  document.getElementById("my_job_form"));

所以这就是我的模型绑定。my_job_formdata-bind="with:jobs"并且我在绑定到的表单内填充一个表estimateTasks。标记是

<tbody data-bind="foreach: $root.estimateTasks">
    <tr>
        <td>
            <input type="text" data-bind="value: EstHr" />
            <input type="hidden" data-bind="value: TaskPerHourCost" />
        </td>
        <td>
            <input type="text" data-bind="value: estLaborSubTotal" disabled />
        </td>
    </tr>
</tbody>

在绑定时,我收到错误

ReferenceError:未定义 estLaborSubTotal

我在这里做错了什么?

4

3 回答 3

3

您正在将计算结果添加到数组中。这个数组只是对estimateTasks observableArray() 求值的结果;

如果我理解你想要做什么。

你最好这样做。这将向项目添加一个名为 estLaborSubTotal 的计算。

var JobPostViewModel = function(){
    var self = this;
    ko.utils.arrayForEach(estimateTasks, function(et) {
        et.estLaborSubTotal  = ko.computed({
            read: function(){
                var estHr = this.EstHr();
                var taskPerHourCost =  this.TaskPerHourCost();
                if(estHr === null)
                    return 0;
                return estHr * taskPerHourCost; 
            },
            owner : et // specify the "this" during evaluation 
        });
    });

    self.estimateTasks = ko.observableArray(estimateTasks);
};

见小提琴

我希望它有所帮助。

于 2013-10-07T10:57:09.513 回答
2

我认为这就是你想要做的 -

function jobPostEstimateTaskModel (task) {
    var self = this;
    // Make some properties of this task observable
    self.name = ko.observable(task.name);
    // Make a computed for each task
    self.estLaborSubTotal = ko.computed(function () {
        return (isNaN(self.EstHr)? 0: +self.EstHr) * (isNaN(self.TaskPerHourCost)? 0: +self.TaskPerHourCost);
    });
}

var JobPostViewModel = function(){
    var self = this;
    self.estimateTasks = ko.observableArray();
    $.each(estimateTasks, function (index, item) {
        self.estimateTasks.push(new jobPostEstimateTaskModel(item));
    }
};

这将遍历您创建的 estimateTasks 普通旧 JavaScript 数组,并为数组中的每个任务添加一个新的 jobPostEstimateTaskModel 对象。它将在任务上创建可观察的属性,例如本例中的名称,然后为数组中的每个项目创建一个计算值。

通过以上述方式调用它,您只是在 observableArray 上创建了一个计算,而不是按照您的意图进行操作。

混淆点之一是您的 ViewModel 有一个名为estimateTasks 的 observableArray 对象,但您在上下文“上方”也有一个变量,它的名称完全相同。考虑将您的不可观察重命名为像 estimateTasksJson 这样的东西来澄清。

编辑

解决此问题的另一种方法是使用原型设计 - 您仍然需要实例化一个对象,例如 jobPostEstimateTaskModel 或任何您想调用的对象,但是您可以将一个可观察对象扩展到每个实例,而不必每次都遍历该代码并将其添加到模型。

于 2013-10-10T17:23:35.880 回答
1

您的问题是foreach当前绑定内容内部是当前数组元素。
而且这个元素没有estLaborSubTotal属性。
你可以<input type="text" data-bind="value: $root.estimateTasks().estLaborSubTotal" disabled />改用。

或者您可以更改视图模型:

var JobPostViewModel = function(){
    var self = this;
    //self.customer = ko.observable(customer);
    //self.job = ko.observable(job);
    //self.estimateMaterials = ko.observableArray(estimateMaterials);
    //self.estimate = ko.observable(estimate);
    self.estimateTasks = ko.observableArray(estimateTasks);
    self.estLaborSubTotal = ko.computed(function () {
        return (isNaN(self.EstHr)? 0: +self.EstHr) * (isNaN(self.TaskPerHourCost)? 0: +self.TaskPerHourCost);
    });
};

并使用<input type="text" data-bind="value: $root.estLaborSubTotal" disabled />.

于 2013-10-11T08:48:56.540 回答