【问题标题】:Knockout access object values from observable array从可观察数组中剔除访问对象值
【发布时间】:2016-10-28 23:16:30
【问题描述】:

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

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

self.stepModels = ko.observableArray(steps)

WizardStep 只有一个 id、name 和一个 personViewModel。 viewModel1、viewModel2 是两个 PersonViewModel,分别包含姓名、年龄和电话号码。

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

我该怎么做?

【问题讨论】:

    标签: knockout.js knockout-3.0


    【解决方案1】:

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

    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"]);

    【讨论】:

      【解决方案2】:

      您可以使用“过滤”数组功能:

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

      注意

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

      【讨论】:

        【解决方案3】:

        前段时间我不得不使用淘汰赛创建一个“向导”类型的功能。你可以这样做:

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

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

        new WizardStep(1, "step1")
        

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

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

        在您的视图中,您可以使用敲除 if binding 有条件地显示或隐藏您当前所在的步骤/只需渲染 self.currentStep() 中保存的 viewModel 并将数据绑定到点击事件。

        如果你真的希望能够通过 stepName 访问,那么你可以使用敲除 arrayFirst 实用程序函数:

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

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

        【讨论】:

          猜你喜欢
          • 2014-10-23
          • 1970-01-01
          • 1970-01-01
          • 2014-01-18
          • 1970-01-01
          • 2015-08-11
          • 1970-01-01
          • 1970-01-01
          • 2012-12-09
          相关资源
          最近更新 更多