【问题标题】:Referencing properties of object constructor outside view model in knockout在淘汰赛中引用视图模型外对象构造函数的属性
【发布时间】:2016-03-21 18:18:22
【问题描述】:

所以,我不完全确定如何表达这个问题,因为它有点二合一。我有一个奇怪的问题,我有一个对象构造函数来从 HTML 表单创建新的“项目”,然后在提交表单时将其推送到 observableArray 中。一切正常,但要引用相关的 observables,我必须使用 'value: Project.title' 或 'value: Project.whatever'。我没有看到在我见过的任何示例中使用了“值:NameOfConstructor.property”。我认为这是因为构造函数在我的视图模型之外。

我的问题是:有没有更好的方法来分配不在我的视图模型中的构造函数中的属性值?换句话说,有没有比“Project.title”等更好或更正确的方法? 我问的部分原因是我的代码中的一件事目前不起作用;淘汰启用属性在我的“新建项目”按钮上不起作用,即使在“标题”输入框中写了一些东西,它也会保持禁用状态。我觉得这是因为它被写成 data-bind='enable: Project.title' 但我不知道怎么写。

我已经包含了一个 jsfiddle 以供参考,尽管它显然由于外部依赖关系而无法正常工作。 https://jsfiddle.net/bmLh0vf1/1/

我的 HTML:

<form id='addBox' action='#' method='post'>
    <label for='pTitle'> Title: </label>
    <input id='pTitle' data-bind='value: Project.title' />
    <br/>
    <label for='pPriority'> Priority </label>
    <select id='pPriority' data-bind='options: priorityOptions, value: Project.priority'></select>
    <br/>
    <button data-bind='enable: Project.title, click: newProject'>New Project</button>
  </form>

还有我的 Javascript:

function Project(title, priority) {
  this.title = ko.observable(title);
  this.priority = ko.observable(priority);
};


function ProjectViewModel() {
  var self = this;
  this.priorityOptions = ko.observableArray(['High', 'Medium', 'Low'])
  this.projectList = ko.observableArray([
    new Project('Create App', 'High')
  ]);
  this.newProject = function() {
    var np = new Project(Project.title, Project.priority);
    self.projectList.push(new Project(Project.title, Project.priority));
    console.log(self.projectList().length);
    if (self.projectList().length > 1) {
      console.log(self.projectList()[1].title());
    };
  }
};

var viewModel = new ProjectViewModel();
$(document).ready(function() {
  ko.applyBindings(viewModel);
});

最后,如果我错过了任何发布约定或者我的代码特别糟糕,我深表歉意。我很新,还在自学。

【问题讨论】:

  • 不相关,但您可以通过将表单控件放入标签中,避免所有通过for/id 将表单控件与标签链接起来的繁琐操作。
  • 哈哈,那会节省我一些时间。很高兴知道!谢谢。

标签: javascript knockout.js


【解决方案1】:

您的代码正在为new Project 创建的对象设置titlepriority 属性,但稍后您希望在Project 本身上看到这些属性。它没有它们; Project 是函数,而不是 new Project 创建的对象。所以Project.titleProject.priority 会给你undefined(而不是可观察的,因此对于value 绑定没有用处)。

相反,有一个您使用的“编辑”Project实例,将输入的value 绑定到编辑实例titlepriority,然后在@ 987654335@ 获取该实例并将其替换为新的新实例。

粗略地说,在ProjectViewModel的构造函数中:

this.editing = ko.observable(new Project());

Project 更新为默认titlepriority

function Project(title, priority) {
  this.title = ko.observable(title || "");
  this.priority = ko.observable(priority || "Medium");
}

在绑定中:

<input id='pTitle' data-bind='value: editing().title' />
<select id='pPriority' data-bind='options: priorityOptions, value: editing().priority'></select>

newProject:

var np = this.editing();
this.editing(new Project());

然后在添加到数组时使用np(而不是另一个new Project)。

这是一个简化的例子:

function Project(title, priority) {
  this.title = ko.observable(title || "");
  this.priority = ko.observable(priority || "Medium");
}


function ProjectViewModel() {
  var self = this;
  this.priorityOptions = ko.observableArray(["High", "Medium", "Low"]);
  this.projects = ko.observableArray();
  this.editing = ko.observable(new Project());
  this.addProject = function() {
    this.projects.push(this.editing());
    this.editing(new Project());
  };
}

ko.applyBindings(new ProjectViewModel(), document.body);
<div>
  <div>
    <label>
      Title:
      <input type="text" data-bind="value: editing().title, valueUpdate: 'input'">
    </label>
  </div>
  <div>
    <label>
      Priority:
      <select data-bind='options: priorityOptions, value: editing().priority'></select>
    </label>
  </div>
  <div>
    <button type="button" data-bind="click: addProject, enable: editing().title">Add Project</button>
  </div>
  <hr>
  <div>Projects:</div>
  <div data-bind="foreach: projects">
    <div>
      <span data-bind="text: title"></span>
      (<span data-bind="text: priority"></span>)
    </div>
  </div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

【讨论】:

  • 啊,这很好用。我必须对我的 HTML 进行一些更改,特别是我的 foreach
      中的
    • 元素的文本(显示在小提琴中,但不是帖子,因为我认为它不相关)必须从 '标题'到'标题()'。否则这是非常有效的。我为 var np 的奇怪之处道歉,我只是在发布之前没有清理我的代码。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-07
  • 1970-01-01
  • 2015-07-27
  • 1970-01-01
  • 2011-12-21
  • 1970-01-01
  • 2014-01-25
相关资源
最近更新 更多