Как добавить к вложенным дочерним элементам наблюдаемого массива нокаута

У меня есть код, в котором можно добавить к нокаутируемому наблюдаемому массиву. Я преобразовываю наблюдаемый массив в объект, не сдвигаю новый объект, а затем сопоставляю этот объект обратно с моделью представления. Это работает, но кажется очень медленным. Это занимает около 2-5 секунд или больше.

function addContact(office) { // Passing in object array of agency. We no it contains correct office and agency ID

        // Assign observable data to new variable then remove old
        // variable from mapping
        var objAgency = ko.toJS(agency);

        vm.agency.removeAll();


        // Fill new object with empty strings and related data
        var objContact = {
            agencyID: office.agencyID._latestValue,
            emailAddress: "",
            firstName: "",
            jobName: "",
            office: "",
            OfficeID: office.officeID._latestValue,
            personID: "",
            surName: "",
            title: ""
        }



        // unshift where office ID match
        for (i in objAgency[0].offices) {
                if (!isNaN(i)) {
                    if (objAgency[0].offices[i].officeID === objContact.OfficeID) {
                        objAgency[0].offices[i].contacts.unshift(objContact); // At i remove one object
                    }
                else {

                }
            } 
        }
        vm.agency([ko.mapping.fromJS(objAgency[0])]);
    }

Я попытался добавить в свой наблюдаемый объект вместо выполнения процесса преобразования и получил следующую ошибку:

Unhandled exception at line 9423, column 13 in http://localhost:13762/scripts/breeze.debug.js

0x800a01b6 - JavaScript runtime error: Object doesn't support property or method 'getProperty'

Этот код вызывает ошибку

for (i in agency._latestValue[0].offices._latestValue) {
            if (!isNaN(i)) {
                if (agency._latestValue[0].offices._latestValue[i].officeID = objContact.OfficeID) {
                    agency._latestValue[0].offices._latestValue[i].contacts._latestValue.unshift([ko.mapping.fromJS(objContact)]);
                }
            }
        }

Посмотрите мой скриншот, как выглядит агентство:

Мой глобальный наблюдаемый массив

Каков правильный способ добавления к этому наблюдаемому массиву? Насколько я понимаю, последнее значение - это механизм отслеживания изменений, поэтому мне не следует вмешиваться в это?


person nick gowdy    schedule 11.09.2013    source источник


Ответы (1)


Если я не ошибаюсь, ._latestValue является свойством, когда вы ссылаетесь на файл Knockout-{версия}.debug.js. Если вы используете нокаут-{версия}.js, этого не будет. В любом случае myObservable._latestValue === myObservable() === ko.unwrap(myObservable). Вы не хотите ссылаться на _latestValue, потому что, когда вы используете уменьшенный JS-файл нокаута в производстве, этот код сломается. Вы должны переписать свой код на:

for (i in agency().offices()) {
    if (!isNaN(i)) {
        if (agency().offices()[i].officeID = objContact.OfficeID) {
            agency().offices()[i].contacts().unshift([ko.mapping.fromJS(objContact)]);
        }
    }
}

И все же это неправильно, потому что ваше if сравнение — это не сравнение, а задание. Используйте ===: if (agency().offices()[i].officeID === objContact.OfficeID)

Это может помочь, но я сомневаюсь в этом, потому что подозреваю, что agency().offices()[i].officID также является наблюдаемым, и в этом случае вам нужно будет использовать () для доступа к его базовому значению.

Другая проблема заключается в том, что вы переводите массив в массив, например:

var arr = ["A", "B"];
arr.unshift(["Z"]);
// Result: [["Z"], "A", "B"];

Поэтому удалите скобки внутри функции .unshift, если только вы не собираетесь добавлять массив в свой массив. Некоторым людям нравится йо чувак.

И хотя вы можете вызывать offices().unshift(value); и манипулировать базовым массивом, предпочтительнее, чтобы вы вызывали unshift для observableArray напрямую следующим образом: offices.unshift(value);, потому что KO затем уведомит подписчиков и обновит DOM. В противном случае вы должны сообщить KO, что значение изменилось. Посмотрите на разницу в этой скрипте.

Надеюсь, это поможет решить вашу проблему.

person nwayve    schedule 11.09.2013