2

Я пытаюсь получить четыре каскадных выпадающие с помощью knockout.js:Используйте knockout.js для 4 каскадных выпадающих на основе иерархии объектов

  1. критерии поиска
  2. Sub Критерии
  3. Значение
  4. Государство

Я смог получить первый каскад (но не другие из-за проблем с привязкой данных), используя код из следующих ссылка:

http://blogs.msdn.com/b/thebeebs/archive/2011/12/01/price-calculator.aspx

Данные для этих выпадающие возвращается к моей бритвы ViewPage как IEnumrable из SearchCriterion с видом MVC, используя переменную ViewBag.CriteriaData. Код для моих классов выглядит следующим образом:

public class SearchCriterion 
{ 
    public string Text { get; set; } 

    public string Value { get; set; } 

    public List<SubCriterion> SubCriteria { get; set; } 
} 

public class SubCriterion 
{ 
    public string SearchCriterionValue { get; set; } 

    public string Text { get; set; } 

    public string Value { get; set; } 

    public List<ColumnValue> ColumnValues { get; set; } 
} 

public class ColumnValue 
{ 
    public string SearchCriterionValue { get; set; } 

    public string SubCriterionValue { get; set; } 

    public string Text { get; set; } 

    public string Value { get; set; } 

    public IEnumerable<StateValue> StateValues { get; set; } 
} 

public class StateValue 
{ 
    public string SearchCriterionValue { get; set; } 

    public string SubCriterionValue { get; set; } 

    public string ColumnValue { get; set; } 

    public IEnumerable<int> InputStateIds { get; set; } 

    public IEnumerable<int> OutputStateIds { get; set; } 

    public int SelectedInputStateId { get; set; } 

    public int SelectedOutputStateId { get; set; } 

    public string Text { get; set; } 

    public string Value { get; set; }  
} 

Вопросы, я столкнулся в следующих частях кода .cshtml:

  1. Что я указываю в этом шаблоне для двух других выпадающие. например третий выпадающий должен быть связан с ColumnValue.Value (ColumnValue является частью SubCriterion)

    <script id='criteriaRowTemplate' type='text/html'> 
        <tr> 
         <td><select data-bind='options: criteriaData, optionsText: "Text", optionsCaption: "Search Criterion", value: SearchCriterion' /></td> 
         <td><select data-bind='visible: SearchCriterion, options: SearchCriterion() ? SearchCriterion().SubCriteria : null, optionsText: "Text", optionsCaption: "Sub Criterion", value: SubCriterion' /></td> 
         <td><select data-bind='visible: SubCriterion, options: SubCriterion() ? SubCriterion().ColumnValues : null, optionsText: "Text", optionsCaption: "Column Value", value: ColumnValue'/></td> 
         <td><select data-bind='visible: ColumnValue, options: ColumnValue() ? ColumnValue().StateValues : null, optionsText: "Text", optionsCaption: "State", value: StateValue'/></td>     
         <td><button data-bind='click: function() { viewModel.removeLine($data) }'>Remove</button></td> 
        </tr> 
    </script> 
    
  2. Правильно ли это?

    var CriteriaLine = function() { 
    this.SearchCriterion = ko.observable(); 
    this.SubCriterion = ko.observable(); 
    this.ColumnValue = ko.observable(); 
    this.StateValue = ko.observable();  
    
    // Whenever the Search Criteria changes, reset the Sub Criteria selection 
    this.SearchCriterion.subscribe(function() { this.SubCriterion(undefined); }.bind(this)); 
    this.SubCriterion.subscribe(function() { this.ColumnValue(undefined); }.bind(this)); 
    this.ColumnValue.subscribe(function() { this.StateValue(undefined); }.bind(this)); 
    

    };

  3. Как сопоставить полный объект C# с объектом Javascript? Это работает, если мы просто первые два выпадающие:

    // Create a Javascript object object with the same property names as the C# object 
    var dataToSearch = $.map(this.lines(), function (line) { return line.StateValue() ? line.StateValue() : undefined; }); 
    
        var SearchObject = new function() { 
          this.StateValues = dataToSearch; 
        }; 
    
        // Convert the object to JSON 
        var searchCriteria = JSON.stringify(SearchObject); 
    
  4. нужно ли что-то изменить здесь для связывания?

    // Apply the data from the server to the variable 
    
    var criteriaData = @Html.Raw(@Json.Encode(ViewBag.CriteriaData)); 
    
    var viewModel = new Criteria(); 
    
    ko.applyBindings(viewModel, document.getElementById("criteriaDiv")); 
    

EDIT:

Я теперь в состоянии заполнить каскадные выпадающие (обновленный код выше). Теперь у меня есть 4 столбца, каждый столбец имеет одно из выпадающих меню. У меня также есть 1 ... n количество строк, добавляемых динамически с помощью Knockoutjs. Таким образом, пользователь может теперь выбирать значения из этих выпадающих списков и добавлять больше строк выпадающих списков, если захочет. Остается только вернуть значения, которые пользователь выбирает для выпадающих списков контроллера (пункт 3 выше). Я не знаю, как это сделать. Любая помощь будет оценена по достоинству.

EDIT 2:

Добавлен рабочий код для товара # 3 и модифицировал классы ColumnValue и StateValue.

+0

Ваша реализация выглядит пугающей, так как у вас есть 4 отдельных раскрывающихся списка, где каждая подпапка вниз зависит от значения родительского элемента (то есть подкритерий зависит от значения критериев). Итак, допустим, у вас есть 10 разных критериев, и по каждому критерию они могут иметь 10 подкатегорий и каждый из этих 10 значений и каждый из этих 10 столбцов. Это 10 + 10^2 + 10^3 + 10^4 значения или возможные 11 110 комбинаций. Вместо этого вам следует избавиться от коллекций List <>, и каждый из них выдает запрос AJAX для заполнения дочернего элемента. – Makotosan

+0

Я бы тоже испугался, если бы у меня было так много случаев. Но выходы здесь не просто зависят от родителя, они также зависят от их дедушки и бабушки. Таким образом, общее количество вариантов довольно ограничено. В раскрывающемся списке критериев поиска будет только 6 значений, под критерии 2-4 значения при макс, выпадающее значение будет иметь в основном 2-3 значения, но в некоторых случаях может иметь около 10 значений, а в последнем выпадающем списке будет всего 2 значения. Я передаю все это обратно как вложенный объект, основанный на моем кеше, без каких-либо отставаний в производительности. Поэтому я не против отправки всех данных, если seomeone может помочь мне с синтаксисом привязки. – Yasir

+0

ОК, поэтому из того, что я могу сказать, вы правильно разбиваете данные C# на объект JavaScript. Я использую $ .json.decode (someObject) (аддон jQuery), но это то же самое. Что касается подписок и изменений данных, я бы пошел с чем-то вроде предложенного ниже, где вы действительно привязаны к вычисленным значениям. Затем вы можете упростить ViewModel, а не пытаться самостоятельно отслеживать все. – farina

ответ

0

Я не уверен, что полностью понимаю ваш вопрос, но я все равно буду бить его :). Я думаю, что вы ищете способ «проверить», если на самом деле время позволяет, чтобы следующий снимок был активным?

Если это так, вы можете приблизиться к нему с точки зрения Computed Observables.В основном, вы привязываете каждое выпадающее меню к вычисленному значению, которое выводится из предыдущих зависимостей.

Позвольте мне написать скрипку, и я покажу вам :)

ОК, дать этому выстрел ... извините за задержку ... http://jsfiddle.net/farina/ZNBcM/3/

+0

Спасибо farina за ответ. Теперь я добавил конкретные вопросы и фрагменты кода, с которыми у меня возникла проблема. В общем, моя проблема связана с синтаксисом привязки для вложенных объектов, подобных тому, который у меня есть. – Yasir

+0

Ahh, только что увидел ваш ответ ... позвольте мне проверить это. – farina

+0

Я обновил свой пример ... надеюсь, что это больше соответствует тому, что вам нужно. – farina

0

Я обновляю ответ, Надежда, это будет помогите новым Comers. Методы связывания иерархических выходов с использованием нокаута JS в MVC

Here вы можете найти хороший пример.