编辑对象数组中新添加的项目并更新DOM [英] Edit newly added items within array of objects and update DOM

查看:53
本文介绍了编辑对象数组中新添加的项目并更新DOM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是 JSFiddle .

对象数组如下所示:

var data = [{
  "ConferenceUsers": [{
    "Id": 3006,
    "ConferenceId": 8,
    "Name": null,
    "Email": "mail@lala.com",
    "UserName": null,
    "PhoneNumber": "234234234234"
  }],
  "Id": 8,
  "Subject": "YYYhaaaaa",
  "StartTime": "2016-05-29T18:30:00",
  "EndTime": "2016-05-29T19:30:00",
  "OrganizerEmail": "elpas@live.com",
  "OrganizerName": "dasdasd",
}, {
  "ConferenceUsers": [{
    "Id": 3013,
    "ConferenceId": 12,
    "Name": null,
    "Email": "dsfdfsdfdsf@dfdfdf.com",
    "UserName": null,
    "PhoneNumber": null
  }],
  "Id": 12,
  "Subject": "dsfsdfdsfsdf",
  "StartTime": "2016-05-31T22:00:00",
  "EndTime": "2016-05-31T23:00:00",
  "OrganizerEmail": "d@adssad.com",
  "OrganizerName": "dsfdsfsdf"
}];

我需要能够添加和编辑新的ConferenceUsers.

I need to be able to add and edit new ConferenceUsers.

添加新用户可以,但是我无法对其进行编辑.

Adding new users works but I can't edit them.

ConferenceUser ViewModel:

var ConferenceUser = function (user) {
    this.ConferenceId = ko.observable(user.ConferenceId);
    this.Email = ko.observable(user.Email);
    this.Id = ko.observable(user.Id);
    this.Name = ko.observable(user.Name);
    this.PhoneNumber = ko.observable(user.PhoneNumber);
}; 

会议列表ViewModel和映射:

var createConferenceUser = function (user) {
    return new ConferenceUser(user);
};

var ConferenceList = function(conferencesJSON) {
  var self = this;

  var users = [];
  for (i = 0; i < conferencesJSON.length; i++) {
      users.push(conferencesJSON[i].ConferenceUsers);
  }

  this.conferences = ko.observableArray(conferencesJSON.map(createConference));
  this.conferenceUsers = ko.observableArray(users.map(createConferenceUser));

  this.addConference = function(conferenceJSON) {
    self.conferences.push(createConference(conferenceJSON));
  };
};

ko.applyBindings(new ConferenceList(data));

问::如何像ConferenceUsers和DOM. rel ="nofollow"> jsFiddle ?

Q: How can I update the existing / newly added ConferenceUsers and the DOM also, like in the jsFiddle?

推荐答案

就像我评论到的:如果您要实际使用具有可观察属性的ConferenceUser视图模型,则可能会弄清楚如何同时使用ConferenceUser视图>创建新,并编辑现有用户.我确实看到了其他一些改进点,所以我认为仍然有必要为您的问题制定答案:

Like I commented: if you were to actually use the ConferenceUser view models with the observable properties, you would probable able to figure out how to both create new, and edit existing users. I do see some other points of improvement though, so I think it's still worth to formulate an answer to your question:

  • 编辑/保存/取消逻辑使您的Conference视图模型混乱不堪,可以很容易地分成自己的小部件
  • 添加更新按钮UI之间进行切换的方式不适用于敲除操作
  • The edit/save/cancel logic is cluttering your Conference view model and can easily be separated into its own little widget
  • The way you're switching between the Add and Update button UI doesn't work well with knockout

我写了一个与体系结构有关的答案,因为我觉得您问题的答案自然来自明确定义的关注点分离.而且因为我喜欢重构:)

I've written an answer that's more about the architecture because I feel that the answer from your question follows naturally from a well defined separation of concerns. And because I enjoy refactoring :)

这是我在搬东西之后的建议.您可以自己决定要使用多少,但是至少可以在代码中找到问题的答案!

Here's my suggestion after having moved stuff around. You can decide for yourself how much of it you'll use, but at least the answer to your question can be found in the code!

会议列表

仅用于管理会议列表.可以很容易地用removeConferencegetConferencesFromServer等扩展.

Only serves to manage a list of conferences. Could easily be extended with removeConference or getConferencesFromServer etc.

var ConferenceList = function(conferencesJSON) {
  this.conferences = ko.observableArray(conferencesJSON.map(Conference.create));

  this.addConference = function(conferenceJSON) {
    self.conferences.push(Conference.create(conferenceJSON));
  };
};

会议

拥有一个ConferenceUser实例列表和一个用于编辑和创建新用户的小部件. 在这里回答您的问题:

Holds a list of ConferenceUser instances and a widget to edit and create new users. This is where your question is answered:

var Conference = function(conferenceJSON) {
  var self = this;
  this.Id = conferenceJSON.Id;

  // Note that we're mapping the plain objects from the json to
  // ConferenceUser instances!
  this.users = ko.observableArray(
    conferenceJSON.ConferenceUsers.map(ConferenceUser.create));

  this.userEditor = new UserEditor(this.users, this.Id);

  this.onUserClick = function(user, event) {
    self.userEditor.edit(user);
  };
};

ConferenceUser

这是我们确保在编辑后更新UI的地方:请注意,可以观察到EmailPhoneNumber属性.我并未为所有属性创建可观察到的对象,以指示并非所有属性都应在UI中进行更改.

This is where we make sure the UI is updated after edits: note that the Email and PhoneNumber properties are observable. I didn't create observables for all properties to indicate not all properties are meant to be changed in the UI.

var ConferenceUser = function(user) {
  this.Email = ko.observable(user.Email);
  this.PhoneNumber = ko.observable(user.PhoneNumber);

  this.ConferenceId = user.ConferenceId;
  this.Id = user.Id;
  this.Name = user.Name;
};

我创建静态创建方法的原因有两个:

I've created a static create method for two reasons:

  1. 它会跟踪闭合中的id以确保其唯一性
  2. Array.prototype.map方法中易于使用.
  1. It keeps track of an id inside a closure to make sure it's unique
  2. It's easy to use inside an Array.prototype.map method.

代码:

ConferenceUser.create = (function() {
  var id = 0;

  return function(userOptions) {
    // Add an ID if not present in options
    return new ConferenceUser(Object.assign(userOptions, {
      Id: userOptions.Id || id++
    }));
  };
}());

UserEditor

(我认为)这是代码的最大改进:编辑器小部件,可帮助您创建,编辑和保存新用户.它公开的方法更容易理解和编写,因为它们不在您的Conference视图模型中.

This is the biggest improvement (I believe) to your code: an editor widget that helps you create, edit and save new users. The methods it exposes are much easier to understand and write because they're not inside your Conference viewmodel.

var UserEditor = function(users, conferenceId) {
  var self = this;

  // Holds the user that's being edited, is null when
  // creating a new user
  this.editing = ko.observable(null);

  this.phoneInput = ko.observable("");
  this.emailInput = ko.observable("");

  this.clear = function() {
    self.phoneInput("");
    self.emailInput("");
  };

  this.add = function() {
    var newUserOptions = {
      Email: self.emailInput(),
      PhoneNumber: self.phoneInput(),
      ConferenceId: conferenceId
    };
    users.push(ConferenceUser.create(newUserOptions));
    self.clear();
  };

  this.edit = function(user) {
    self.editing(user);

    self.phoneInput(user.PhoneNumber());
    self.emailInput(user.Email());
  };

  this.reset = function() {
    self.editing(null);
    self.clear();
  };

  this.save = function() {
    var currentUser = self.editing();

    currentUser.Email(self.emailInput());
    currentUser.PhoneNumber(self.phoneInput());

    self.reset();
  };

};

现在,在完成所有这些代码之后,您将看到HTML非常简单.这是您的编辑窗口小部件:

Now, after all this code, you'll see your HTML is very straight forward. Here's your edit widget:

<div data-bind="with: userEditor">
  <input type="tel" placeholder="phone number" 
    data-bind="value: phoneInput" />
  <input type="email " placeholder="email" 
    data-bind="value: emailInput" />
  <!-- ko ifnot: editing -->
  <button data-bind="click: add">Add</button>
  <!-- /ko -->
  <!-- ko if: editing -->
  <button data-bind="click: save">Save</button>
  <button data-bind="click: reset">Cancel</button>
  <!-- /ko -->
</div>

有很长的故事可以解决,但是,如果您到目前为止已经做到了:这是一个更新的小提琴! https://jsfiddle.net/e2ox4doj/

Kind of a long story to get to the fix, but if you've made it this far: here's an updated fiddle! https://jsfiddle.net/e2ox4doj/

这篇关于编辑对象数组中新添加的项目并更新DOM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆