2012-04-11 7 views
2

My View привязан к модели и отображает несколько выпадающих списков, а их число и параметры основаны на некоторых свойствах модели.KnockoutJS Как привязать набор выпадающих списков к наблюдаемому массиву

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

Каждый выпадающий список отображается с помощью следующего кода:

@for (var i = 0; i < Model.ProductProfiles.Count; i++) 
     { 
      var productProfile = Model.ProductProfiles[i]; 
      if (productProfile.IsVarying) 
      { 
       var lastItem = 0;   
       <div class="tab-pane" id="@productProfile.Name">       
        @for (var j = 0; j < productProfile.Attributes.Count; j++) 
        {   

         <text>@productProfile.Attributes[j].Name</text>              
         @Html.DropDownListFor(m => m.ProductProfiles[i].SelectedValues[j], (SelectList)ViewData["Levels_" + i + "_" + j], 
         new { @class = "ddl-levels" }) 
         <br /> 
        } 
       </div> 
      } 
     } 

В DropDownLists правильно заполнены и значение по умолчанию установлено правильно (с использованием как модели и выберите список, переданный в ViewData).

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

массив [0] [ "0", "1", "3", "1", ....] где массив [0] относится к Model.ProductProfiles [0], а второй размер массива содержит выбранные значения для ddl, как показано в цикле for ?

Я попытался установить мой вид модель так просто, как

var viewModel = { 
    selectedValues: ko.observableArray([])    
}; 

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

@Html.DropDownListFor(m => m.ProductProfiles[i].SelectedValues[j], (SelectList)ViewData["Levels_" + i + "_" + j], 
         new { @class = "ddl-levels", data_bind = "value: productProfiles([" + i + "][" + j + "])" }) 

К сожалению, это не сработало ...

Надеюсь, что было ясно, иначе я был бы рад прояснить, когда его попросят. Есть ли кто-нибудь, кто может мне помочь?

Благодаря

EDIT: на основе комментариев советов, я разделить многомерный массив на 3 наблюдаемые массивы как следующее:

var viewModel = {   
    selectedValuesProd0: ko.observableArray(), 
    selectedValuesProd1: ko.observableArray(), 
    selectedValuesProd2: ko.observableArray() 
} 

, а затем я изменил HTML код

var observableArrayProduct = "selectedValuesProd0"; 
        if (i == 1) 
        { 
         observableArrayProduct = "selectedValuesProd1"; 
        } 
        else if (i == 2) 
        { 
         observableArrayProduct = "selectedValuesProd2"; 
        } 

@Html.DropDownListFor(m => m.ProductProfiles[i].SelectedValues[j], (SelectList)ViewData["Levels_" + i + "_" + j], new { @class = "ddl-levels", data_bind = "value: " + observableArrayProduct + "()[" + j+ "]" }) 

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

На этом этапе я начинаю думать, что позиционный доступ не работает, но если это так, что еще я могу сделать?

EDIT 2: РЕШЕННЫЙ!

Хорошо, я отсутствовал ключевой шаг: каждый элемент в наблюдаемом массиве сам по себе является наблюдаемой величина, поэтому я установил его, как следующее:

var viewModel = {   
    selectedValuesProd0: ko.observableArray(ko.utils.arrayMap(selectedValuesPerProduct[0], function(item) { 
     return ko.observable(item); 
    })), 
    selectedValuesProd1: ko.observableArray(ko.utils.arrayMap(selectedValuesPerProduct[1], function(item) { 
     return ko.observable(item); 
    })), 
    selectedValuesProd2: ko.observableArray(ko.utils.arrayMap(selectedValuesPerProduct[2], function(item) { 
     return ko.observable(item); 
    })) 
} 

Где selectedValuesPerProduct является двухразмерным массивом, построенным с использованием модели передается из кода на стороне сервера в представление (после сериализации).

Надеюсь, это поможет!

+0

Я думаю, что ваш последний оператор будет оценивать значение data-bind = "value: productProfiles ([0] [1])", (это не eval из массива, eval - data-bind = "value: productProfiles() [ 0] [1] "). В любом случае, даже если вы измените порядок скобок, это не сработает должным образом (массивы нокаутов не могут быть многомерными). Конечно, вы можете создать наблюдаемый массив наблюдаемых массивов, но я бы советовал об этом из-за ремонтопригодности. Подумайте о создании нормальной модели просмотра вместо использования многомерного массива. – Artem

+0

Спасибо Artem за ваш комментарий. Поэтому вы предлагаете создать один одномерный наблюдаемый массив для каждого набора выпадающих списков: это не очень важное решение, но если ничего не поделаешь, я попробую, спасибо! – s0nica

ответ

0

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

Хорошо, я отсутствовал ключевой шаг: каждый элемент в наблюдаемом массиве само по себе является наблюдаемой величиной, поэтому я установил это так:

var viewModel = {   
selectedValuesProd0: ko.observableArray(ko.utils.arrayMap(selectedValuesPerProduct[0], function(item) { 
    return ko.observable(item); 
})), 
selectedValuesProd1: ko.observableArray(ko.utils.arrayMap(selectedValuesPerProduct[1], function(item) { 
    return ko.observable(item); 
})), 
selectedValuesProd2: ko.observableArray(ko.utils.arrayMap(selectedValuesPerProduct[2], function(item) { 
    return ko.observable(item); 
})) 

}

Где selectedValuesPerProduct является двухразмерным массивом, построенным с использованием модели передается на стороне сервера коды на View (после сериализации).

0

Я рекомендовал бы прохождение падение падения вниз, как так: {firstArray: [1,2,3], secondArray: [4,5,6]}

В основном вам не экономить любую работу так, как вы предложите сделать это вместо этого. Вы можете сделать «firstArray» и «secondArray» не дружественными человеку, как ваш индексист. Хотя я не уверен, почему это была бы ценная цель;) Я стараюсь поддерживать код, где я могу. Любой, кто приходит после вас и видит многоуровневого индексатора, не оценит вашу умность или позже их головную боль.

+0

Ops Я забыл об этом вопросе. Первоначально мой наблюдаемый массив был двумерным массивом, потому что я хотел быть независимым от количества продуктов, которые я должен будет отображать, и количества атрибутов для каждого продукта. Поскольку двумерный наблюдаемый массив не будет работать в нокауте, мне пришлось отказаться от числа продуктов, разделяя их на n наблюдаемых массивов, каждый из которых длиннее числа атрибутов на продукт. Таким образом, не существует многоуровневого подхода, каждый наблюдаемый массив является монометрическим и содержит выбранные значения для каждого из раскрывающихся меню. – s0nica

Смежные вопросы