2016-09-22 5 views
6

저는 asp.net MVC 애플리케이션을 작성 중이며 동적 UI 항목에 Knockout.js를 사용하기로 결정했습니다. 지금까지 많은 도움이 된 훌륭한 프레임 워크입니다.Knockout.js로 게시하기

하지만 나는 해결할 수없는 두 가지 문제에 직면하여 유용한 정보를 찾았습니다. 내가 가지고있는 것을 보여주기 위해 코드로 시작한 다음, 내가 성취하고자하는 것을 설명하려고 노력할 것입니다.

C#의 ViewModel

Project ViewModel


ProjectServicesViewModel


ProjectPositionsViewModel

내 HTML/라 Zor의 녹아웃 모듈

var Project = function (project) { 
 
\t var self = this; 
 
\t self.Id = ko.observable(project ? project.Id : 0); 
 
\t self.CustumerCompany = ko.observable(project ? project.CustumerCompany : ""); 
 
\t self.CustomerRepresentative = ko.observable(project ? project.CustomerRepresentative : ""); 
 
\t self.ProjectTitle = ko.observable(project ? project.ProjectTitle : ""); 
 
\t self.WWSNumber = ko.observable(project ? project.WWSNumber : ""); 
 
\t self.AqStatus = ko.observable(project ? project.AqStatus : ""); 
 
\t self.Completed = ko.observable(project ? project.Completed : ""); 
 
\t self.StartDate = ko.observable(project ? project.StartDate : ""); 
 
\t self.EndDate = ko.observable(project ? project.EndDate : ""); 
 
\t self.ProjectLeader = ko.observable(project ? project.ProjectLeader : ""); 
 
\t self.Deputy = ko.observable(project ? project.Deputy : ""); 
 
\t self.SalesConsultant = ko.observable(project ? project.SalesConsultant : ""); 
 
\t self.Service = ko.observableArray(project ? project.Service : []); 
 
}; 
 

 
var ProjectService = function (projectService) { 
 
\t var self = this; 
 
\t self.Id = ko.observable(projectService ? projectService.Id : 0); 
 
\t self.Number = ko.observable(projectService ? projectService.Number : ""); 
 
\t self.Name = ko.observable(projectService ? projectService.Name : ""); 
 
\t self.Positions = ko.observableArray(projectService ? projectService.Positions : []); 
 
}; 
 

 
var ServicePosition = function (servicePosition) { 
 
\t var self = this; 
 
\t self.Id = ko.observable(servicePosition ? servicePosition.Id : 0); 
 
\t self.Number = ko.observable(servicePosition ? servicePosition.Number : ""); 
 
\t self.Name = ko.observable(servicePosition ? servicePosition.Name : ""); 
 
\t self.PerformanceGroup = ko.observable(servicePosition ? servicePosition.PerformanceGroup : ""); 
 
\t self.PerformanceGroupPrice = ko.observable(servicePosition ? servicePosition.PerformanceGroupPrice : ""); 
 
\t self.Remarks = ko.observable(servicePosition ? servicePosition.Remarks : ""); 
 
}; 
 

 
var ProjectCollection = function() { 
 
\t var self = this; 
 

 
\t self.project = ko.observable(new Project()); 
 
\t self.projectServices = ko.observableArray([new ServicePosition()]); 
 
\t self.servicePositions = ko.observableArray([new ServicePosition()]); 
 

 
\t self.addService = function() { 
 
\t \t self.projectServices.push(new ProjectService()); 
 
\t \t console.log(self.projectServices); 
 
\t }; 
 
\t self.removeService = function (projectService) { 
 
\t \t self.projectServices.remove(projectService); 
 
\t }; 
 

 

 

 
\t self.saveProject = function() { 
 
\t \t self.project().Service = self.projectServices; 
 
\t \t console.log(self.projectServices); 
 
\t \t console.log(self.project()); 
 

 
\t \t var token = $('[name=__RequestVerificationToken]').val(); 
 

 
\t \t $.ajax({ 
 
\t \t \t type: "POST", 
 
\t \t \t url: "/LeistungManager/CreateProject", 
 
\t \t \t data: { __RequestVerificationToken: token, model: ko.toJS(self.project()) }, 
 
\t \t \t dataType: "json", 
 
\t \t \t cache: false, 
 
\t \t \t async: true, 
 
\t \t \t success: function (response) { 
 

 
\t \t \t }, 
 
\t \t \t complete: function (response) { 
 
\t \t \t \t console.log(response); 
 
\t \t \t } 
 
\t \t }); 
 
\t }; 
 

 
}; 
 
ko.applyBindings(new ProjectCollection());
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 

 
<div class="row"> 
 
    <div class="col-md-6"> 
 
    <div class="widget"> 
 
     <div class="widget-heading"> 
 
     <h3 class="widget-title">Project Services</h3> 
 
     <div> 
 
      <form class="form-inline"> 
 
      <p> 
 
       <div class="form-group"> 
 
       <label>WWS-Number</label> 
 
       <input class="form-control" placeholder="Number" data-bind="value: $root.Number" /> 
 
       <label>WWS-Number</label> 
 
       <input class="form-control" placeholder="Name" data-bind="value: $root.Name" /> 
 
       <button class="btn btn-primary" data-bind="click: addService">Add</button> 
 
       </div> 
 
      </p> 
 
      </form> 
 
     </div> 
 
     </div> 
 
     <div class="widget-body"> 
 
     <table data-bind="visible: projectServices().length > 0 " class="table"> 
 
      <thead> 
 
      <tr> 
 
       <th> 
 
       Number 
 
       </th> 
 
       <th> 
 
       Service Name 
 
       </th> 
 
       <th> 
 

 
       </th> 
 
      </tr> 
 
      </thead> 
 
      <tbody data-bind="foreach: projectServices"> 
 

 
      <tr> 
 
       <td data-bind="text: $parent.Number"></td> 
 
       <td data-bind="text: $parent.Name"></td> 
 
       <td> 
 
       <button class="btn btn-success">Edit</button> 
 
       <button class="btn btn-danger" data-bind="click: $root.removeService">Delete</button> 
 
       </td> 
 
      </tr> 
 

 
      </tbody> 
 
     </table> 
 

 
     </div> 
 
    </div> 
 
    </div> 
 
</div>

내 결과를 보인다

Design

문제점 수 (Nr) (1)

W 등 암탉 나는 모든 정보를 입력하고 몇 가지 프로젝트 서비스 항목을 추가하면 내 컨트롤러 모델을 수신하지만 서비스의 속성은 비어 있으며 이유를 파악할 수 없습니까? 내가 뭘 잘못하고있어?

Result

문제 수 (Nr) 2

다음 서비스 패널 (디자인의 스크린 샷 참조) 나는 다른 거의 같은 패널을 구축 할 것입니다하지만 윈도우에서 동일 의존해야 기능을 목록에 추가로 Project 프로젝트 서비스 패널에서 항목을 선택합니다. 예 :

오른쪽에있는 프로젝트 서비스 패널의 첫 번째 항목을 선택하면 ADD 버튼이 패널에 표시되어 항목을 다른 목록에 추가 할 수 있습니다. 한 항목에 정보를 입력하면 다른 항목을 선택하고 거기에 배치 할 수 있으며 프로젝트 서비스 선택에 따라 패널을 업데이트해야합니다. 나는 이런 종류의 결과를 어떻게 달성 할 수 있는지 예제, 기사 또는 튜토리얼을 찾을 수 없다. 도움이되는 모든 종류의 도움! 당신을 위해

+0

컨트롤러가 요청을 구문 분석하는 방법을 알아야합니다. 당신은 당신의 ajax 옵션에서'contentType : 'application/json;'을 사용할 수있다. – janmvtrinidad

+0

이것도 알고 있습니다. –

+0

contentType : 'application/json'을 설정하고 데이터를 문자열 화해야합니다. 'data : JSON.stringify ({__RequestVerificationToken : token, model : ko.toJS (self.project())} })'http://stackoverflow.com/questions/14591437/deserialising-json-into-nested-view-model-in-controller를 참조하십시오. 'dataType'은 서버로부터 데이터를받을 때 ** 관련 **입니다. 데이터를 보낼 때'contentType'을 설정해야합니다 – nemesv

답변

3

문서를 읽은 후 문제를 해결할 수 있습니다. 그래서 여기에 노력하고 있습니다 JS 코드를 HTML 내 질문에서와 동일합니다

/// <reference path="../jquery-3.1.0.intellisense.js" /> 
 

 

 
\t var ProjectModel = function (project) { 
 
\t \t var self = this; 
 
\t \t self.Id = ko.observable(project ? project.Id : 0); 
 

 
\t \t self.CustumerCompany = ko.observable(project ? project.CustumerCompany : ""); 
 

 
\t \t self.CustomerRepresentative = ko.observable(project ? project.CustomerRepresentative : ""); 
 

 
\t \t self.ProjectTitle = ko.observable(project ? project.ProjectTitle : ""); 
 

 
\t \t self.WWSNumber = ko.observable(project ? project.WWSNumber : ""); 
 

 
\t \t self.AqStatus = ko.observable(project ? project.AqStatus : ""); 
 

 
\t \t self.Completed = ko.observable(project ? project.Completed : ""); 
 

 
\t \t self.StartDate = ko.observable(project ? project.StartDate : ""); 
 

 
\t \t self.EndDate = ko.observable(project ? project.EndDate : ""); 
 

 
\t \t self.ProjectLeader = ko.observable(project ? project.ProjectLeader : ""); 
 

 
\t \t self.Deputy = ko.observable(project ? project.Deputy : ""); 
 

 
\t \t self.SalesConsultant = ko.observable(project ? project.SalesConsultant : ""); 
 

 
\t \t self.Service = ko.observableArray(project ? project.Service : []); 
 

 
\t }; 
 

 

 
\t // #endregion 
 

 
\t // #region Project Service Model 
 

 
\t var ProjectServiceModel = function (projectService) { 
 
\t \t var self = this; 
 
\t \t self.Id = ko.observable(projectService ? projectService.Id : 0); 
 

 
\t \t self.Number = ko.observable(projectService ? projectService.Number : ""); 
 

 
\t \t self.Name = ko.observable(projectService ? projectService.Name : ""); 
 

 
\t \t self.Positions = ko.observableArray(projectService ? projectService.Positions : []); 
 

 
\t \t self.isEditing = ko.observable(true); 
 

 
\t \t self.isActive = ko.observable(false); 
 

 
\t \t self.countSelf = ko.computed(function() { 
 
\t \t \t if (self.Positions().length > 0) { 
 
\t \t \t \t return true; 
 
\t \t \t } 
 
\t \t \t else { 
 
\t \t \t \t return false; 
 
\t \t \t } 
 

 
\t \t }, 
 
\t self); 
 

 
\t }; 
 

 

 
\t // #endregion 
 

 
\t // #region Position Model 
 
\t var ServicePositionModel = function (servicePosition) { 
 
\t \t var self = this; 
 
\t \t self.Id = ko.observable(servicePosition ? servicePosition.Id : 0); 
 

 
\t \t self.Number = ko.observable(servicePosition ? servicePosition.Number : ""); 
 

 
\t \t self.Name = ko.observable(servicePosition ? servicePosition.Name : ""); 
 

 
\t \t self.PerformanceGroup = ko.observable(servicePosition ? servicePosition.PerformanceGroup : ""); 
 

 
\t \t self.PerformanceGroupPrice = ko.observable(servicePosition ? servicePosition.PerformanceGroupPrice : ""); 
 

 
\t \t self.Remarks = ko.observable(servicePosition ? servicePosition.Remarks : ""); 
 

 
\t \t self.isEditing = ko.observable(servicePosition ? servicePosition.isEditing : false); 
 

 
\t \t self.isActive = ko.observable(false); 
 

 
\t }; 
 

 
\t // #endregion 
 

 

 
\t var ProjectViewModel = function() { 
 
\t \t var self = this; 
 

 
\t \t self.project = ko.observable(new ProjectModel()); 
 

 
\t \t self.projectServices = ko.observableArray([]); 
 

 
\t \t // #region InitData 
 

 
\t \t 
 

 
\t \t self.selectedPerformanceGroup = ko.observableArray([]); 
 
\t \t self.AqStatusTypeData = ko.observableArray([]); 
 
\t \t self.PerformanceGroupTypeData = ko.observableArray([]); 
 
\t \t $.ajax({ 
 
\t \t \t url: "/LeistungManager/InitializeData", 
 
\t \t \t dataType: "json", 
 
\t \t \t success: function (json) { 
 
\t \t \t \t self.AqStatusTypeData(json.AqStatusType); 
 
\t \t \t \t self.PerformanceGroupTypeData(json.PerformanceGroupType); 
 
\t \t \t } 
 
\t \t }); 
 

 

 
\t \t self.testOptions = function() { 
 
\t \t \t 
 
\t \t \t self.selectedPerformanceGroup; 
 
\t \t \t debugger; 
 
\t \t } 
 

 
\t \t // #endregion 
 

 
\t \t // #region Service Functions 
 
\t \t self.addService = function() { 
 
\t \t \t var object = new Object(); 
 

 
\t \t \t object.isEditing = true; 
 
\t \t \t self.projectServices.push(new ProjectServiceModel(object)); 
 

 
\t \t \t self.isServiceSelected(false); 
 

 
\t \t }; 
 

 

 
\t \t self.saveService = function (projectService) { 
 
\t \t \t projectService.isEditing(false); 
 

 
\t \t }; 
 

 
\t \t self.editService = function (projectService) { 
 
\t \t \t projectService.isEditing(true); 
 

 
\t \t }; 
 

 
\t \t self.removeService = function (projectService) { 
 
\t \t \t self.projectServices.remove(projectService); 
 

 
\t \t }; 
 

 

 
\t \t self.isServiceSelected = ko.observable(false); 
 

 
\t \t self.selectedServiceData = ko.observable(new Object()); 
 

 
\t \t self.selectService = function (serviceRowData) { 
 
\t \t \t if (!serviceRowData.isEditing()) { 
 
\t \t \t \t self.isServiceSelected(true); 
 

 
\t \t \t \t serviceRowData.isActive(true); 
 

 
\t \t \t \t self.selectedServiceData(serviceRowData); 
 

 
\t \t \t } 
 

 
\t \t }; 
 

 
\t \t // #endregion 
 

 

 
\t \t // #region Position Functions 
 
\t \t self.addPosition = function() { 
 
\t \t \t var object = new Object(); 
 

 
\t \t \t object.isEditing = true; 
 
\t \t \t self.selectedServiceData().Positions.push(new ServicePositionModel(object)); 
 

 
\t \t }; 
 

 

 
\t \t self.savePosition = function (servicePosition) { 
 
\t \t \t servicePosition.isEditing(false); 
 

 
\t \t }; 
 

 
\t \t self.editPosition = function (servicePosition) { 
 
\t \t \t servicePosition.isEditing(true); 
 

 
\t \t }; 
 

 
\t \t self.removePosition = function (servicePosition) { 
 
\t \t \t self.selectedServiceData().Positions.remove(servicePosition); 
 

 
\t \t }; 
 

 

 
\t \t self.isPositionSelected = ko.observable(false); 
 

 
\t \t self.selectedPositionData = ko.observable(ServicePositionModel(new Object())); 
 

 
\t \t self.selectPosition = function (positionRowData) { 
 
\t \t \t if (!positionRowData.isEditing()) { 
 
\t \t \t \t self.isPositionSelected(true); 
 

 
\t \t \t \t positionRowData.isActive(true); 
 

 
\t \t \t \t self.selectedPositionData(positionRowData); 
 

 

 
\t \t \t } 
 

 
\t \t }; 
 

 
\t \t // #endregion 
 

 
\t \t self.saveProject = function() { 
 
\t \t \t self.project().Service = self.projectServices; 
 
\t \t \t self.project().Service().Positions = self.servicePositions; 
 

 
\t \t \t var token = $('[name=__RequestVerificationToken]').val(); 
 

 

 
\t \t \t $.ajax({ 
 
\t \t \t \t type: "POST", 
 
\t \t \t \t url: "/LeistungManager/CreateProject", 
 
\t \t \t \t data: { __RequestVerificationToken: token, model: ko.toJS(self.project()) }, 
 

 
\t \t \t \t dataType: "json", 
 
\t \t \t \t cache: false, 
 
\t \t \t \t async: true, 
 
\t \t \t \t success: function (response) { 
 

 
\t \t \t \t }, 
 

 
\t \t \t \t complete: function (response) { 
 
\t \t \t \t \t console.log(response); 
 

 
\t \t \t \t } 
 

 
\t \t \t }); 
 

 
\t \t }; 
 

 

 
\t }; 
 

 
ko.applyBindings(new ProjectViewModel());

마법이 selectedServiceData을 관찰 변수를 만드는이었다 selectPosition에 버튼 클릭에 기능을 건네 . 그런 다음 선택한 항목 배열 및 데이터를 사용할 수 있습니다.

누구든지 코드에 대한 자세한 설명이나 도움이 필요한 경우 알려 주시기 바랍니다.

2

: 당신이 당신의 요청을 구문 분석하는 방법을 알 수있는 컨트롤러에 대한 귀하의 아약스 요청에 contentType: 'application/json;'을 추가 할 수 있습니다 1

문제.

문제 2 코드 예를 들어 fiddle을 참조하십시오. 다른 바인딩 컨텍스트를 사용할 위치를 알기 위해이 값을 documentation으로 확인할 수 있습니다.

+0

콘텐츠 유형에 대해서는 문제가되지 않습니다. 컨트롤러는 Vm에서 observableArray가 아닌 요소에 대한 정보를 받고 이미 제공된 dataType이 있기 때문입니다. 문제에 관해서는 nr. 2 나는 이미 그 문서를 읽고, 나는 나의 목표에 대한 모범이 필요하다. –