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

コードに欠落している部分がありますが、主な問題は、計算されたオブザーバブル自体ではなく、その関数で計算されたオブザーバブルの初期値を返していることです。したがって、最終的には、計算されたオブザーバブルではなく、値にバインドします。

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

計算されたものを返すだけで、呼び出さないでください(追加で())。

更新されたコード:

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

注:指定したコードでは、計算内のitems配列を参照していません。アイテムが変更されたときに計算が更新されるようにするには、items配列を使用する必要があります。それ以外の場合、計算はアイテムに依存しないため、更新する理由はありません。

于 2013-01-27T00:27:20.597 に答える
0

問題はgetStudentAverage、計算されたオブザーバブルを返す単なる関数であることです。それ自体がオブザーバブルでなければなりません。StudentId パラメーターを使用するようにしようとしているようですが、それは設計のエラーの回避策にすぎません。

モデルが必要な場合はStudent、学生の配列をループして、 のようなものを呼び出すことができますstudent.getAverage。もう ID をこっそり入力する必要はありません。

于 2013-01-27T00:07:23.367 に答える