带映射插件的Knockout.js工作流 [英] Knockout.js Workflow with Mapping plugin

查看:188
本文介绍了带映射插件的Knockout.js工作流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定我了解Knockout.js在内部遵循的工作流程.我有一个使用映射插件动态定义的ViewModel.它的形状是:

I'm not sure I understand the workflow Knockout.js follows internally. I have a ViewModel that is defined dynamically, using the mapping plugin. Its shape is:

{ current: { foo: 'foo', bar: 'bar', id: 0 }
, ids:     [1,2,3,4,5] 
}

每个ids都对应一个可以属于current的值.现在,复杂性出现了,因为在填充我的viewModel的初始ajax请求中,服务器使用current: null进行响应.我已经编写了将第一个idids列表中删除的代码,并运行另一个ajax查询来填充current.看起来像这样:

Each of those ids corresponds to a value that can belong in current. Now, the complication comes in because in the initial ajax request to populate my viewModel, the server responds with current: null. I have written code to take the first id out of the list of ids and run another ajax query to populate current. That looks like this:

var ViewModel = function (data) {
  var self = this;
  ko.mapping.fromJS(data, {}, self);

  self.head = function () {
    if (self.promptIds().length != 0) {
      var nextId = _.head(self.promptIds());
      self.promptIds(_.tail(self.promptIds()));
      $.getJSON("my-url" + "/" + nextId, function (data) {
        self.current(ko.mapping.fromJS(data));
      });
    }
  }
}


$('document').ready ( function () {
  $.getJSON("view-model-route", function (data) {
    viewModel = new ViewModel(data);
    viewModel.head();
    ko.applyBindings(viewModel);
  });
});

请注意,在第二个块中,我创建了一个新的ViewModel对象,并在其上调用了head().填充viewModel.current()对象后,我将在完整的viewModel上调用ko.applyBindings.我可以确认所有尘埃落定后,viewModel.current不是null.但是我仍然遇到错误:

Notice that in the second block, I create a new ViewModel object and I call head() on it. Once the viewModel.current() object is populated, I call ko.applyBindings on the complete viewModel. I can confirm that when all the dust settles, viewModel.current is not null. But I am still getting the error:

Uncaught TypeError: Unable to parse bindings.
  Bindings value: text: current().foo
  Message: Cannot read property 'foo' of null

我想做淘汰赛原本不打算做的事情吗?我是否需要另一层抽象?您将如何处理这种情况?

Am I trying to do something Knockout wasn't designed to do? Do I need another layer of abstraction? How would you approach this situation?

推荐答案

在调用ko.applyBindings时首先评估绑定.

The bindings are first evaluated when you call ko.applyBindings.

因此,如果此时您的current属性包含null,则通常会出现Cannot read property 'foo' of null异常.

So if your current property contains null by that time then this it is normal that you get an Cannot read property 'foo' of null exception.

对此问题有多种解决方案:

There are multiple solution to this problem:

  • 使用空对象初始化current,因此将正确解析current().foo(但其值为undefined):

  • Initialize current with an empty object, so the current().foo will be parsed correctly (but its value be undefined):

viewModel = new ViewModel(data);
viewModel.head();
viewModel.current({});
ko.applyBindings(viewModel);

  • 您可以在绑定中添加一个额外条件,以检查current是否具有某些值:

  • You can add an extra condition in your binding to check that current has some value:

    <input type="text" data-bind="value: current() && current().foo" />
    

  • 或者最好和最推荐的选择是使用 with绑定如果您要处理嵌套属性:

  • Or probably the best and most recommended option is to use the with binding if you are dealing with nested proeprties:

    <!-- ko with: current -->
        <input type="text" data-bind="value: foo" />
    <!-- /ko -->
    

  • 演示 JSFiddle .

    这篇关于带映射插件的Knockout.js工作流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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