【问题标题】:Posting Collection with Knockout.js使用 Knockout.js 发布集合
【发布时间】:2017-01-30 13:55:58
【问题描述】:

我正在编写一个 asp.net MVC 应用程序,并决定尝试使用 Knockout.js 来处理动态 UI 内容。这是一个很棒的框架,到目前为止它对我帮助很大。

但我遇到了 2 个我无法解决的问题,并找到了任何有用的信息。 我将从代码开始向您展示我所拥有的,然后我将尝试解释我想要实现的目标。

C# 视图模型



我的 HTML/Razor 和淘汰模块

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

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

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

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

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

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



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

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

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

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

};
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>

我的结果看起来像

问题编号 1

当我输入所有信息并添加几个项目服务项时,我的控制器接收模型但服务的属性为空,我不知道为什么?我做错了什么?

问题编号 2

在项目服务面板旁边(查看设计截图)我将构建另一个几乎相同的面板,但在该窗口中,相同的添加到列表功能应该取决于我在项目服务面板中选择的项目。 例如:

如果我在右侧的 Project Service 面板中选择了第一个项目,应该会出现带有 ADD 按钮的面板,这样我就可以将项目放到另一个列表中。在我将信息放入一个项目后,我可以选择另一个并放在那里,面板应该根据项目服务选择进行更新。 我在任何地方都找不到如何实现这种结果的示例、文章或教程。 任何形式的帮助都会有所帮助!

【问题讨论】:

  • 控制器需要知道如何解析你的请求。你可以在你的ajax选项中使用contentType: 'application/json;'
  • 它知道并且没有这个
  • 您确实需要设置 contentType: 'application/json' 并将您的数据字符串化,所以 data: JSON.stringify({ __RequestVerificationToken: token, model: ko.toJS(self.project()) })stackoverflow.com/questions/14591437/…dataType在您从服务器接收数据时才相关。当您发送数据时,您需要设置contentType
  • 我创建了这个小提琴jsFiddle 乍一看似乎你的services.add方法有问题。最初添加了一个空的ProjectService

标签: javascript c# asp.net asp.net-mvc knockout.js


【解决方案1】:

为您:

问题一你可以在你的ajax请求中添加contentType: 'application/json;',让控制器知道如何解析你的请求。

问题 2 请参阅 fiddle 以了解您的代码示例。您可以查看此documentation,以便了解在何处使用不同的绑定上下文。

【讨论】:

  • 关于内容类型 - 这不是问题。因为控制器接收有关 Vm 中不可观察数组的元素的信息,并且已经提供了 dataType。关于问题编号。 2 我已经阅读了该文档,我需要一个目标示例
【解决方案2】:

经过一段时间阅读文档后,我设法解决了我的问题。 所以这里是工作 JS 代码 HTML 与我的问题相同:

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


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

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

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

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

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

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

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

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

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

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

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

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

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

	};


	// #endregion

	// #region Project Service Model

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

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

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

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

		self.isEditing = ko.observable(true);

		self.isActive = ko.observable(false);

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

		},
	 self);

	};


	// #endregion

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

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

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

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

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

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

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

		self.isActive = ko.observable(false);

	};

	// #endregion


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

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

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

		// #region InitData

		

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


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

		// #endregion

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

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

			self.isServiceSelected(false);

		};


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

		};

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

		};

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

		};


		self.isServiceSelected = ko.observable(false);

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

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

				serviceRowData.isActive(true);

				self.selectedServiceData(serviceRowData);

			}

		};

		// #endregion


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

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

		};


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

		};

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

		};

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

		};


		self.isPositionSelected = ko.observable(false);

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

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

				positionRowData.isActive(true);

				self.selectedPositionData(positionRowData);


			}

		};

		// #endregion

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

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


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

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

				},

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

				}

			});

		};


	};

ko.applyBindings(new ProjectViewModel());

神奇之处在于创建 selectedServiceData 可观察变量,并在单击按钮时将其传递给 selectPosition 函数。之后,我可以使用选定的 Item 数组和数据。

如果有人需要更详细的解释或代码帮助,请告诉我。

【讨论】:

    猜你喜欢
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 2015-07-06
    相关资源
    最近更新 更多