2014-02-18 2 views
2

Полностью новый для нокаута, и я пытаюсь отобразить ответ JSON от сервера к конкретным моделям с использованием плагина отображения нокаута. Модели вложены, и я пытаюсь переопределить конструкцию объекта, используя обратный вызов create даже во вложенных моделях. Тем не менее, похоже, что мои параметры отображения читаются правильно. Пример JSON:Как настроить создание сопоставления нокаутов в вложенной модели?

{ 
    "EmployeeFeedbackRequestSubmissions": [ 
     { 
      "EmployeeFeedbackRequestSubmissionId": 0, 
      "Employee": "John Smith0", 
      "EmployeesWorkedWith": [ 
       { 
        "EmployeeName": "Joe Smith", 
        "ProjectsWorked": [ 
         { 
          "ProjectName": "Document Management Console" 
         }, 
         { 
          "ProjectName": "Performance Eval Automation" 
         }, 
         { 
          "ProjectName": "Business Tax Extensions" 
         } 
        ] 
       }, 
       { 
        "EmployeeName": "Michael Jones", 
        "ProjectsWorked": [ 
         { 
          "ProjectName": "Document Management Console" 
         }, 
         { 
          "ProjectName": "Performance Eval Automation" 
         }, 
         { 
          "ProjectName": "Business Tax Extensions" 
         } 
        ] 
       }, 
       { 
        "EmployeeName": "Jason Smith", 
        "ProjectsWorked": [ 
         { 
          "ProjectName": "Document Management Console" 
         }, 
         { 
          "ProjectName": "Performance Eval Automation" 
         }, 
         { 
          "ProjectName": "Business Tax Extensions" 
         } 
        ] 
       }, 
       { 
        "EmployeeName": "Robert Will", 
        "ProjectsWorked": [ 
         { 
          "ProjectName": "Document Management Console" 
         }, 
         { 
          "ProjectName": "Performance Eval Automation" 
         }, 
         { 
          "ProjectName": "Business Tax Extensions" 
         } 
        ] 
       } 
      ] 
     } 
     // more EmployeeFeedbackRequestSubmissions 
    ] 
} 

Варианта Mapping:

var mappingOptions = { 
    // overriding default creation/initialization code 
    'EmployeeFeedbackRequestSubmissions': { 
     create: function (options) { 
      return (new(function() { 
       this.EmployeeHeading = ko.computed(function() { 
        return "Performance Evaluation Employee: " + this.Employee(); 
       }, this); 

       ko.mapping.fromJS(options.data, {}, this); 
      })()); 
     }, 
      'EmployeesWorkedWith': { 
      create: function (options) { 
       return new instance.EmployeesWorkedWithModel(options.data); 
      } 
     } 
    } 
}; 

Пример скрипка с полным, например: http://jsfiddle.net/jeades/9ejJq/2/

Результатом должен быть возможностью использовать вычисленный nameUpper из EmployeesWorkedWithModel. Я также открыт для предложений о лучшем способе сделать это, поскольку это может быть не лучший способ справиться с этим.

ответ

2

Вы были почти там. Прямо к ней работает: http://jsfiddle.net/jiggle/na93A/

Варианты Отображения объекта не должны быть вложенными, отображение подключить будет искать отображение из названия, когда вы передаете их ko.mapping.fromJSON

So ваш объект опций отображения должен быть один уровнем:

var self = this; 

    self.mappingOptions = { 
     // overriding default creation/initialization code 
     'EmployeeFeedbackRequestSubmissions': { 
      create: function (options) { 
       return (new(function() { 
        this.EmployeeHeading = ko.computed(function() { 
         return "Performance Evaluation Employee: " + this.Employee(); 
        }, this); 

        ko.mapping.fromJS(options.data, self.mappingOptions, this); 
       })()); 
      } 
     }, 
     'EmployeesWorkedWith': { 
       create: function (options) { 
        // return new instance.EmployeesWorkedWithModel(options); 
        return (new(function(){ 
         ko.mapping.fromJS(options.data, {}, this); 

         this.nameUpper = ko.computed(function() { 
          return this.EmployeeName().toUpperCase(); 
         }, this); 
        })()); 
       } 
     } 

    }; 

Примечание Я использовал «я» в качестве локальной ссылки на «это» вместо «например», просто чтобы сделать код более удобным для чтения (как вы использовали " экземпляр "в главной модели просмотра).

Я также сделал объект mappingOptions частью части FeedbackViewModel, так как мы должны передать это в вызов mapping.fromJS, поэтому, когда он видит уровень EmployeesWorkedWith в данных, он будет иметь для него mappingOptions.

От:

ko.mapping.fromJS(options.data, {}, this); 

To:

ko.mapping.fromJS(options.data, self.mappingOptions, this); 

Вы можете переместить код создания на уровне 'EmployeesWorkedWith' в создании (можно вызвать функцию, но я держал его как показано выше, подобно тому, как вы создавали уровень «EmployeeFeedbackRequestSubmissions».

Вы можете избавиться от экземпляра.EmployeesWorkedWithModel fu вообще.

рабочая скрипку можно найти здесь:

http://jsfiddle.net/jiggle/na93A/

В качестве альтернативы, вы можете создать отдельное mappingOptions объекта, когда вы находитесь в создании для «EmployeeFeedbackRequestSubmissions» и не имеете отображения для всех уровней в одном объекте , который можно увидеть в этой скрипте http://jsfiddle.net/jiggle/Avam7/

В зависимости от стиля кодирования, который вы предпочитаете, и было бы важно разделить их, если бы у вас были разные потребности в сопоставлении для разных уровней, и у них было одно и то же имя коллекции.

например.

Сотрудники

Сотрудник

Сотрудники (возможно, потребуется различные computeds и т.д. на этом уровне)

Если да, то вы будете использовать второй вариант (отделите mapOptions an d перейти на уровень, который будет его использовать)

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

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

+0

Спасибо за несколько примеров и объяснений! –

+0

Джейсон, приветствую вас, спасибо за ваш комментарий, когда у вас появится возможность попробовать ответы, вы заметите, что с ответами beauXjames вы потеряете свои вычисленные, например. nameUpper и т. д., потому что в его примере фактически не выполняется сопоставление для уровня EmployeesWorkedWith ваших данных, это просто создание данных. Привет, Джон. –

+0

Да, спасибо, что указали это. Моя основная проблема заключалась в попытке присоединить дополнительные вычислимые свойства и функции к вложенным моделям. В противном случае мне не потребовалось бы переопределять любую конструкцию объекта. Еще раз спасибо. –

1

Хорошая вещь с ko.mapping - как автоматизирован процесс. Посмотрите результаты в http://jsfiddle.net/9ejJq/26/

Вы заметите, как мы используем только одно объявленное сопоставление, чтобы отбросить вещи.

feedbackMappingOptions = { 
    create: function (options) { 
     return new FeedbackViewModel(options.data); 
    } 
}; 

Оттуда каждая модель представления запускает отображение для своих дочерних объектов. Вы могли бы дойти до создания параметра сопоставления для каждого или, как вы видите для конечного объекта ProjectsWorked под EmployeesWorkedWith, мы просто бросаем данные прямо при сопоставлении, а ko.mapping делает все остальное. Надеюсь, это помогло.

+0

О, и помните ... как только вы предоставите собственный способ создания в своих сопоставлениях, вам нужно объявить свои свойства в модели представления, которую вы создаете ... они не будут объявлены автоматически. – beauXjames

+0

Awesome. Спасибо за помощь и время! –

+0

beauXjames, но он проиграл свое имяUpper, которое было причиной того, что он делал картографирование в первую очередь? –

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