剔除视图模型外部的对象构造函数的属性 [英] Referencing properties of object constructor outside view model in knockout

查看:46
本文介绍了剔除视图模型外部的对象构造函数的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我不太确定如何表达这个问题,因为它是二合一的.我有一个奇怪的问题,我有一个对象构造函数从HTML表单创建新的项目",然后在提交表单时将其推入observableArray.一切正常,但要引用相关的可观察对象,我必须使用值:Project.title"或值:Project.whatever".在我所看到的任何示例中,我都没有看到过'value:NameOfConstructor.property'.我认为这样做是因为构造函数在我的视图模型之外.

So, I'm not entirely sure how to phrase this question as it's sort of two in one. I'm having a weird issue where I have an object constructor to create new 'projects' from an HTML form which are then pushed into an observableArray when the form is submitted. Everything works fine but to reference the related observables I have to use 'value: Project.title' or 'value: Project.whatever'. I haven't seen 'value: NameOfConstructor.property' used in any of the examples I've seen. I assume this works this way because the constructor is outside of my view model.

我的问题是:是否有更好的方法在不在我的视图模型中的构造函数中分配属性的值?换句话说,有没有比"Project.title"更好或更正确的方法? 我之所以提出这样的要求,部分原因是因为代码中的一件事目前无法正常工作;剔除启用属性在我的新建项目"按钮上不起作用,即使在标题"输入框中写了一些内容,该属性也保持禁用状态.我感觉是因为它被写为data-bind ='enable:Project.title',但我不知道该怎么写.

My question is this: Is there a better way to assign the value of a property in a constructor that is not in my view model? In other words, is there a better or more correct way than 'Project.title', ect? I ask partially because one thing in my code doesn't work currently; the knockout enable property doesn't work on my "New Project" button, it stays disabled even if there is something written in the 'title' input box. I have the feeling it's because it's written as data-bind='enable: Project.title' but I can't figure how else to write it.

我包括了一个jsfiddle作为参考,尽管由于外部依赖性,它显然不起作用. https://jsfiddle.net/bmLh0vf1/1/

I've included a jsfiddle for reference though it obviously isn't working because of external dependencies. 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:

And my 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);
});

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

Lastly, I apologize if I've missed any posting conventions or if my code is especially bad. I'm very new and still teaching myself.

推荐答案

您的代码正在对new Project创建的对象设置titlepriority属性,但是稍后您希望看到这些属性. Project本身.它没有它们. Project是函数,而不是new Project创建的对象.因此,Project.titleProject.priority将为您提供undefined(并且不是可观察的对象,因此对于value绑定不是有用的目标).

Your code is setting title and priority properties on the object created by new Project, but then later you're expecting to see those properties on Project itself. It doesn't have them; Project is the function, not the object created by new Project. So Project.title and Project.priority will give you undefined (and not an observable, and so not useful targets for the value binding).

相反,请使用编辑" Project 实例,将输入的value绑定到编辑实例titlepriority,然后在newProject抓住那个实例,然后用一个新的实例替换它.

Instead, have an "editing" Project instance that you use, binding the value of the inputs to the editing' instances title and priority, and then in newProject grab that instance and replace it with a new, fresh one.

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

Roughly speaking, in ProjectViewModel's constructor:

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).

Then use np (instead of another new Project) when adding to the array.

这是一个简化的示例:

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>

这篇关于剔除视图模型外部的对象构造函数的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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