从可观察数组中剔除访问对象值

Knockout access object values from observable array

我的视图模型有一个可观察的 WizardSteps 对象数组,

var steps = [
        new WizardStep(1, "step1", viewModel1), 
        new WizardStep(2, "step2", viewModel2),
    ];

self.stepModels = ko.observableArray(steps)

WizardStep 只有一个 ID、名称和一个 personViewModel。 viewModel1、viewModel2 是两个 PersonViewModel,其中包含姓名、年龄和 phone 号码。

我可以通过索引 $root.stepModels()[0].viewModel.name 访问 stepModels 并获取 viewModel1 的名称。但我需要通过步骤名称访问它,例如'step1'。

我该怎么做?

可以使用"filter"数组函数:

var foundModel = <container object>.stepModels().filter(function(model) { return model.name === "modelName"; })[0];
if(!!foundModel) {
    // some code working with found model
}

备注

最好在模型中保留这样的函数,而不是将计算放入 html 标记中。

如果您需要经常访问模型,创建一个使用步长值作为键的对象可能会更容易和更快:

var WizardStep = function(id, name) {
  this.id = id;
  this.name = name;
};

var steps = [
  new WizardStep(1, "step1"),
  new WizardStep(2, "step2"),
];

var stepsByName = steps.reduce(function(result, step) {
  result[step.name] = step;
  return result;
}, {});

// The object:
console.log(JSON.stringify(stepsByName, null, 2));

// Get a step by name:
console.log(stepsByName["step1"]);

前段时间我不得不使用 knockout 创建一个 'wizard' 类型的特征。你可以这样做:

var steps = ko.observableArray([
        { stepName: "step1", person: viewModel1 },
        { stepName: "step1", person: viewModel2 }
    ]);

首先,值得注意的是,如果您在填充后不打算修改它,则您的步骤数组不需要是可观察的。其次,您可能也不需要步骤编号 - 我假设这就是行中 1 所代表的内容:

new WizardStep(1, "step1")

因为数组是有序的,所以您正在存储您已经拥有的信息,这些信息包含在您的 steps 数组中每个元素的索引中。即 steps[0] 将是 step1 等等。如果您需要跟踪您在向导中的位置,您可以在 viewModel 中创建一个可观察对象和一个函数来设置您当前所在的步骤,如下所示:

var self = this;
self.currentStep = ko.observable(0); // starting step

self.goToStep = function(index){
  self.currentStep(index); 
};

或者您可以:

var self = this;
self.currentStep = ko.observable(steps()[0]);  // starting step

self.goToStep = function(index){
  self.currentStep(steps()[index]);
  // if you only need the viewModel associated with this step you could use:
  self.currentPerson(steps()[index].viewModel.name);
};

在您的视图中,如果绑定有条件地显示或隐藏您当前所在的步骤,您可以使用敲除/简单地呈现 self.currentStep() 中保存的 viewModel 并将数据绑定到点击事件,例如。

如果你真的希望能够访问 stepby stepName 那么你可以使用 knockouts arrayFirst 实用函数:

self.getStepByName = function(stepName){
  return ko.utils.arrayFirst(steps(), function(step) {
        return step.stepName() === stepName;
  });
};

我会让你填写空白和遗漏的声明。您还可以使用计算或可写计算来做一些事情。归根结底,剥猫皮的方法有很多种。我确信这里提供的任何一种解决方案都是可行的。