2016-01-02 2 views
0

У меня есть загрузочная вкладка bootstrap, и я хочу отображать динамическое содержимое при выборе вкладки. Ajax возвращает массив результатов. Каждый результат имеет Price, Logo, Companyname и массив Covers. Каждая обложка имеет Price, MaxCover, Необязательный и Описание. Остальной код html здесь link, но теперь я хочу вернуть более сложный тип.Матрица связывания нокаутом сложного типа с ajax

<script type='text/javascript'> 

var cover = new 
    { 
     Price: ko.observable(), 
     MaxCover: ko.observable(), 
     Optional: ko.observable(), 
     Description: ko.observable(), 
    } 
var result = new 
    { 
     Price: ko.observable(), 
     InsLogo: ko.observable(), 
     CompanyName: ko.observable(), 
     Covers: ko.observableArray() 
    }; 

var tab = function (Id, name, selected) { 
    this.Id = Id; 
    this.name = name; 
    this.Results = ko.observableArray(); 
    this.isSelected = ko.computed(function() { 
     return this === selected(); 
    }, this); 
} 

var ViewModel = function() { 
    var self = this; 
    self.selectedTab = ko.observable(); 
    self.tabs = ko.observableArray([ 
     new tab(0, 'Tab1', self.selectedTab), 
     new tab(1, 'Tab2', self.selectedTab), 
     new tab(2, 'Tab3', self.selectedTab) 
    ]); 
    self.selectedTab(self.tabs()[0]); 

    self.selectedTab.subscribe(function() { 
     $.ajax({ 
      url: '@Url.Action("GetSection")', 
      data: { Id: self.selectedTab().Id }, 
      type: 'GET', 
      success: function (data) { 
       self.selectedTab().Results(data.Results); //Here I want to fill the results!!!!!! 
      } 
     }); 

    }); 

} 
ko.applyBindings(new ViewModel()); 

+1

любая проблема, в частности, вы сталкиваетесь? насколько я вижу данные, это не так сложно. добавьте скрипку, чтобы я мог помочь вам. cheers –

+1

Вам не нужно использовать 'new' с объектными литералами' {} '- на самом деле это ошибка. Использовать '{}' достаточно. – Tomalak

ответ

3

Ваш подход хорошо с несколькими небольшими глюками. Некоторые предложения по его улучшению:

  • Создайте свои модели просмотра, чтобы они инициализировались из объекта параметров.
  • Не вводите зависимости между режимами просмотра, когда вам этого не нужно. Я думаю о собственности isSelected здесь, об этом можно позаботиться в представлении. Например, когда внутри foreach: tabs: data-bind="css: {selected: $data === $parent.selectedTab()}"
  • У вас есть вопрос синхронизации: Подписаться на selectedTab первый, затем инициализировать его с self.selectedTab(self.tabs()[0]);. Это должно быть очевидно, почему. (Как правило, полезно разделить создание области видимости на «настройку» и фазу «init».)
  • Только отправьте запрос Ajax для сведений о вкладке, когда данные вкладки все еще пусты.
  • Подписчики получают новое значение наблюдаемого в качестве аргумента, используют его.
  • Наблюдаемые являются функциями:
    • Если вы хотите сохранить ответ Ajax в них вы можете использовать их в качестве обратного вызова непосредственно.
    • Точно так же вы можете использовать их в качестве обработчика событий:
      data-bind="click: $parent.selectedTab".
  • JS конвенции является использование PascalCase для имен конструкторов (например, в ViewModels) и camelCase для всех других идентификаторов.

Со всем, что мы получим:

function Tab(data) { 
    this.Id = data.Id; 
    this.name = data.name; 
    this.Results = ko.observableArray(); 
} 
function ViewModel(data) { 
    var self = this; 

    // setup 
    self.selectedTab = ko.observable(); 
    self.selectedTab.subscribe(function (selectedTab) { 
     if (selectedTab.Results()) return; 
     $.get('@Url.Action("GetSection")', {Id: selectedTab.Id}).done(selectedTab.Results); 
    }); 

    // init 
    self.tabs = ko.observableArray(ko.utils.arrayMap(data.tabs, function (tabData) { 
     return new Tab(tabData); 
    })); 
    self.selectedTab(self.tabs()[0]); 
} 
ko.applyBindings(new ViewModel({ 
    tabs: [ 
     {Id: 0, name: 'Tab1'}, 
     {Id: 1, name: 'Tab2'}, 
     {Id: 2, name: 'Tab3'} 
    ] 
})); 

Для преобразования простых структур данных, которые приходят с сервера (например, вашими результаты массивов и покрытия) в структуру ViewModels, наблюдаемых и наблюдаемых массивов я рекомендую глядя в mapping plugin.

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