2012-02-08 3 views
0

Я пытаюсь заполнить мою модель просмотра некоторыми вариантами выпадающего списка из базы данных. Я хочу отслеживать выбранный объект, потому что у него есть свойства, которые я использую в пользовательской привязке в другом месте.Knockout.JS Наблюдаемый массив через AJAX, привязанный к DropDownList

Я инициализирую наблюдаемое значение «пустым», чтобы оно было правильно установлено, когда происходит привязка, и моя пользовательская привязка работает. Как только сервер отвечает, я преобразую данные в наблюдаемый массив, и в раскрывающемся списке отображаются параметры.

Вот код JavaScript:

ko.bindingHandlers.jq_fade = { 
    init: function (element, valueAccessor) { 
     // Initially set the element to be instantly visible/hidden depending on the value 
     var value = valueAccessor(); 
     $(element).toggle(ko.utils.unwrapObservable(value)); // Use "unwrapObservable" so we can handle values that may or may not be observable 
    }, 
    update: function (element, valueAccessor) { 
     // Whenever the value subsequently changes, slowly fade the element in or out 
     var value = valueAccessor(); 
     ko.utils.unwrapObservable(value) ? $(element).fadeIn() : $(element).fadeOut(); 
    } 
}; 

function Firm(id, name, outsideCounsel) { 
    this.name = name; 
    this.id = id; 
    this.outsideCounsel = outsideCounsel; 
} 

function RequestViewModel() { 
    var self = this, 
     ONE_DAY = 1000 * 60 * 60 * 24; 


    self.firm = ko.observable(new Firm(-1, "", false)); 

    $.post(ajaxAddress + 'LoadFirms', function (data) { 
     var mappedFirms = $.map(data.d, function (item) { 
      return new Firm(item.OrganizationLookupID, item.OrganizationLookupName, item.IsExternalCounselFirm); 
     }); 
     self.availableFirms(mappedFirms); 
     self.firm(self.availableFirms()[0]); 
    }); 
} 


$(document).ready(function() { 
    model = new RequestViewModel(); 
    ko.applyBindings(model); 
}); 

Вот соответствующий HTML

<span data-bind="jq_fade: firm().outsideCounsel"> 
    Outside Counsel 
    <input type="text" id="outsideCounsel" data-bind="value: outsideCounsel" /> 
</span> 

Я хочу, чтобы DIV, чтобы показать только, если выбранная фирма является внешний адвокат. Если удалить линию data-bind="jq_fade: firm().outsideCounsel, все будет хорошо. Если я делаю вызовы $.post() синхронно, он работает. Я думаю, что это неправильно с моей функцией init в jq_fade.

Ошибка я получаю это:

Uncaught Error: Unable to parse bindings. Message: TypeError: Cannot call method 'outsideCounsel' of undefined; Bindings value: jq_fade: firm().outsideCounsel()

Я понимаю, что Knockout говорит мне, я просто не знаю, как firm() никогда не может быть undefined, потому что я установил начальное значение.

+0

Вы уверены, что сервер возвращает какие-либо данные? Если это не так, то эта строка self.firm (self.availableFirms() [0]); может сбросить self.firm до undefined –

+0

Возможно, вам нужно указать «json» в качестве последнего параметра в $ .post. –

+0

Да Я уверен, что сервер возвращает данные. Вы правы в определении «json». Я делаю это дальше на странице, но с вызовом '$ .ajaxSetup(). – arb

ответ

1

Если вы связываете availableFirms() к DropDownList, я предполагаю, что вы также обязаны firm() в том же список, так что, когда другой выбрано из списка, firm() получает автоматически обновляются, и все ваши привязки автоматически обновляется.

Если это так, вам не нужно устанавливать firm() вообще, так как в любом случае он будет установлен на первый элемент в раскрывающемся списке.

Смотрите пример 3 здесь:

http://knockoutjs.com/documentation/options-binding.html

var viewModel = { 
    availableCountries : ko.observableArray([ 
     new country("UK", 65000000), 
     new country("USA", 320000000), 
     new country("Sweden", 29000000) 
    ]), 
    selectedCountry : ko.observable() // Nothing selected by default 
}; 

Попробуй, как и выше, не специально настройки firm() и посмотреть, если это ошибки снова