0

我有以下对象:

function Category (id, name, weight) {
    this.categoryId = ko.protectedComputed(id);
    this.name  = ko.protectedComputed(name); 
    this.weight = ko.protectedComputed(weight);
    // this.dirtyFlag = new ko.dirtyFlag(this);
}

function Item (id, name, categoryId, gradeMax) {
    this.itemId = ko.observable(id);
    this.name  = ko.observable(name); 
    this.categoryId = ko.observable(categoryId);
    this.gradeMax = ko.observable(gradeMax);
}

function Grade (gradeId, itemId, studentId, studentName, grade) {
    this.gradeId = gradeId;
    this.itemId =  itemId;
    this.studentId  =  studentId; 
    this.studentName = studentName;
    this.grade = ko.observable(grade);
}

var viewModel =  function () {
    var self = this;

    self.items = ko.observableArray([
        new Item(3, "Homework 3", 1, 10),
        new Item(1, "Homework 1", 1, 20),
        new Item(2, "Homework 2", 1, 30),
        new Item(4, "Quiz", 3, 5)
    ]);

    self.categories = ko.observableArray([ 
        new Category(1, "Homework", 50) , 
        new Category(2, "Test", 25), 
        new Category(3, "Quiz", 25)          
    ]);

    self.grades = ko.observableArray([  
        //grades for item 4
        new Grade(10, 4,1, "Olivo,  Omar", 2)  ,   
        new Grade(11, 4,2, "Mercado,  Coryann",5),           
        new Grade(12, 4,3, "Pena,  Juan", 4) 
    ]);

    self.addItem = function () {
        var randId = int.rand(); 
        var newItem = new Item(randId , "new item", 1, 100);
        self.items.push(newItem);

        self.selectedItem(newItem);           
    };

    self.getStudentAverage = function (studentId) {
        return ko.computed(function () 
        {
            var total = 0,
            numOfItems = 0;

            // Get the grades for the assignment for this student
            var studentGrades =   ko.utils.arrayFilter(self.grades(), function(grade) {                          
                return grade.studentId == studentId;
            }); 

            // Calculate the Weighted Average
            if ( self.isWeighted() == true ){
                var faceAverage= 100;

                return tempAvg ;
            }  
        }, this)();
    };
};

HTML

<tbody data-bind="foreach: { data : $root.students, as : 'student' }  "  >                  
   <tr> 
        <td>
                <span data-bind="text: student.studentId" ></span>   - 
                <span data-bind="text: student.studentName" ></span>  
        </td>

        <td> 
             <span data-bind="text:  $root.getStudentAverage(student.studentId) "> </span> 
        </td>

        <!-- ko foreach: { data : $root.items, as : 'item' }  -->             
        <td > <!--   <span data-bind="css: { dirty : $root.getGrade(item.itemId(), student.studentId).grade.isDirty()}"></span> -->
              <input  class="grade-input" data-bind="value: $root.getGrade(item.itemId(), student.studentId).grade " />  
        </td>          
        <!-- /ko -->
    </tr>
</tbody>

问题是vm.getStudentAverage()当我插入新项目时没有更新。我试图弄清楚为什么这对我不起作用。我想在插入新项目后计算每个学生的平均值。

这是一个演示问题的小提琴。

4

2 回答 2

2

您的代码中缺少部分,但主要问题似乎是您在该函数中返回计算的 observable 的初始值,而不是计算的 observable 本身。所以最后,你绑定的是一个值,而不是计算出来的 observable。

self.getStudentAverage = function (studentId)
{
    return ko.computed(function () 
    {
        // code...
    }, this)(); // <-- you are returning the result of the computed
};

只需返回计算值,不要调用它(使用 extra ())。

更新代码:

self.getStudentAverage = function (studentId)
{
    return ko.computed(function () 
    {
        // code...
    }, this);
};

注意:在您提供的代码中,您甚至没有引用计算中的 items 数组。您必须使用 items 数组,以便在 items 更改时更新计算。否则,计算不依赖于项目,因此没有理由更新它。

于 2013-01-27T00:27:20.597 回答
0

问题是这getStudentAverage只是一个返回计算出的 observable 的函数。它本身必须是可观察的。我看到您尝试让它使用 studentId 参数,但这只是您设计中错误的解决方法:

您需要一个Student模型,然后您可以遍历一组学生并调用类似student.getAverage. 无需再偷偷输入ID。

于 2013-01-27T00:07:23.367 回答